XSLT参数身份转换,无需输入XML [英] XSLT param identity transform without input XML

查看:74
本文介绍了XSLT参数身份转换,无需输入XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了好几天,但没有成功.我有以下XSLT,它不接受任何输入XML,但具有一个XML参量:

I'm trying this for days and no success. I have following XSLT which doesn't take any input XML, but has one param as XML:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:param name="products">
        <products author="Jesper">
            <product id="p1">
                <name>Delta</name>
                <price>800</price>
                <stock>4</stock>
                <country>Denmark</country>
            </product>
            <product id="p2">
                <name>Golf</name>
                <price>1000</price>
                <stock>5</stock>
                <country>Germany</country>
            </product>
            <product id="p3">
                <name>Alfa</name>
                <price>1200</price>
                <stock>19</stock>
                <country>Germany</country>
            </product>
            <product id="p4">
                <name>Foxtrot</name>
                <price>1500</price>
                <stock>5</stock>
                <country>Australia</country>
            </product>
            <!-- p5 is a brand new product -->
            <product id="p5">
                <name>Tango</name>
                <price>1225</price>
                <stock>3</stock>
                <country>Japan</country>
            </product>
        </products>
    </xsl:param>
    <xsl:template match="@*|node()" name="initial">
        <xsl:copy>
            <xsl:apply-templates select="$products / @*|node()" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="products">
        <xsl:copy>
            <xsl:attribute name="dateUpdated">
      <xsl:value-of select="current-dateTime()" />
    </xsl:attribute>
            <xsl:apply-templates select="$products / @*|node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这是来自此处的示例,我只是使用输入XML作为参数. 我的问题是如何在XSLT参数上进行身份转换并使该转换有效?

This is example from here I just used input XML as param. My question is how to do identity transform on XSLT param and make this transformation work?

推荐答案

进行以下更改以使您的XSLT 2.0转换生效:

  1. as="node()"添加到xsl:param.
  2. 匹配(忽略的)输入XML的根元素,并 <xsl:apply-templates select="$products"/>从那里得到 从参数XML开始.
  3. 从其他人的xs:apply-templates中删除$products 模板.
  4. 从您的身份模板中删除name="initial".
  1. Add as="node()" to the xsl:param.
  2. Match the root element of the (ignored) input XML and <xsl:apply-templates select="$products"/> from there to get started on the param XML.
  3. Remove $products from the xs:apply-templates of your other templates.
  4. Remove name="initial" from your identity template.

然后,使用上述更新进行XSLT 2.0转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:param name="products" as="node()">
    <products author="Jesper">
      <product id="p1">
        <name>Delta</name>
        <price>800</price>
        <stock>4</stock>
        <country>Denmark</country>
      </product>
      <product id="p2">
        <name>Golf</name>
        <price>1000</price>
        <stock>5</stock>
        <country>Germany</country>
      </product>
      <product id="p3">
        <name>Alfa</name>
        <price>1200</price>
        <stock>19</stock>
        <country>Germany</country>
      </product>
      <product id="p4">
        <name>Foxtrot</name>
        <price>1500</price>
        <stock>5</stock>
        <country>Australia</country>
      </product>
      <!-- p5 is a brand new product -->
      <product id="p5">
        <name>Tango</name>
        <price>1225</price>
        <stock>3</stock>
        <country>Japan</country>
      </product>
    </products>
  </xsl:param>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="products">
    <xsl:copy>
      <xsl:attribute name="dateUpdated">
        <xsl:value-of select="current-dateTime()" />
      </xsl:attribute>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="/">
    <xsl:apply-templates select="$products"/>
  </xsl:template>
</xsl:stylesheet>

将产生所需的输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<products dateUpdated="2014-12-09T06:38:15.8-05:00" author="Jesper">
   <product id="p1">
      <name>Delta</name>
      <price>800</price>
      <stock>4</stock>
      <country>Denmark</country>
   </product>
   <product id="p2">
      <name>Golf</name>
      <price>1000</price>
      <stock>5</stock>
      <country>Germany</country>
   </product>
   <product id="p3">
      <name>Alfa</name>
      <price>1200</price>
      <stock>19</stock>
      <country>Germany</country>
   </product>
   <product id="p4">
      <name>Foxtrot</name>
      <price>1500</price>
      <stock>5</stock>
      <country>Australia</country>
   </product>
   <product id="p5">
      <name>Tango</name>
      <price>1225</price>
      <stock>3</stock>
      <country>Japan</country>
   </product>
</products>

XSLT 1.0解决方案

OP的转换被声明为使用XSLT 2.0,但是对于以后想要在XSLT 1.0中进行此操作的任何人,都可以通过document(''):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:param name="products">
    <products author="Jesper">
      <product id="p1">
        <name>Delta</name>
        <price>800</price>
        <stock>4</stock>
        <country>Denmark</country>
      </product>
      <product id="p2">
        <name>Golf</name>
        <price>1000</price>
        <stock>5</stock>
        <country>Germany</country>
      </product>
      <product id="p3">
        <name>Alfa</name>
        <price>1200</price>
        <stock>19</stock>
        <country>Germany</country>
      </product>
      <product id="p4">
        <name>Foxtrot</name>
        <price>1500</price>
        <stock>5</stock>
        <country>Australia</country>
      </product>
      <!-- p5 is a brand new product -->
      <product id="p5">
        <name>Tango</name>
        <price>1225</price>
        <stock>3</stock>
        <country>Japan</country>
      </product>
    </products>
  </xsl:param>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="products">
    <xsl:copy>
      <xsl:attribute name="dateUpdated">
        <xsl:value-of select="current-dateTime()" />
      </xsl:attribute>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="/">
    <xsl:apply-templates select="document('')//xsl:param[@name='products']/products"/>
  </xsl:template>
</xsl:stylesheet>

这篇关于XSLT参数身份转换,无需输入XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆