-2

关于马丁答案的问题:Martin Honnen 的答案效果很好,但不适用于根元素。假设我有“汽车”作为根元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="foo">
        <cars>
            <car1 />
            <car2 />
        </cars>
    </xsl:template>
</xsl:stylesheet>

我想获得:

<xsl:template match="foo">
    <cars>
        <car1 />
        <car2 />
        <TANK />
    </cars>
</xsl:template>

为此,我会使用:

<xsl:template match="cars" >
  <xsl:copy>
    <xsl:apply-templates/>
    <TANK />
  </xsl:copy>
</xsl:template> 

它输出准确的输入,而不改变任何东西。我可以试试:

<xsl:template match="/" >
  <xsl:copy>
    <xsl:apply-templates/>
    <TANK />
  </xsl:copy>
</xsl:template> 

但它会将 TANK 节点放在样式表之外,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="order">
    <cars>
        <car1/>
        <car2/>
    </cars>
</xsl:template>
</xsl:stylesheet><TANK/>

如何获得汽车内部的坦克元素?

原始问题:我有一个用于转换 XML 的 XSL:

XML_format1 -> XSL1 -> XML_format2

我需要转换第一个 XSL 文件(使用第二个 XSL)以获得第三个 XSL 文件,该文件将输出第三种格式的 XML。简而言之:

XSL1 -> XSL2 -> XSL3

XML_format1 -> XSL3 -> XML_format3

使用以下样式表,我可以复制第一个 XSL 的内容并跳过某些节点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 

<xsl:template match="@*|node()">
   <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
</xsl:template>

<xsl:template match="//skipThisNode"/>

</xsl:stylesheet>

我的问题:除此之外,我还需要更改一些节点的结构(添加一些东西),从这个:

<car>
    <color>green</color>
    <fuel>petrol</fuel>
</car>

对此:

<car>
    <color>green</color>
    <fuel>petrol</fuel>
    <topSpeed>99</topSpeed>
</car>

LE:我可以创建一个模板来匹配我需要添加子节点的特定节点,如下所示:

<xsl:template match="car">
    <color>
        <!-- existing value-of -->  
    </color>
    <fuel>
         <!-- existing value-of --> 
    </fuel>
    <topSpeed>
        <!-- * new value-of * -->  
    </topSpeed>
</xsl:template>

但这似乎有点过头了。有没有更简单的方法来实现我想要的?

4

1 回答 1

4

我宁愿用

<xsl:param name="newSpeed" select="99"/>

<xsl:template match="car">
  <xsl:copy>
    <xsl:apply-templates/>
    <topSpeed>
      <xsl:value-of select="$newSpeed"/>
    </topSpeed>
  </xsl:copy>
</xsl:template>

这使处理链保持正常,允许您添加模板以car在需要时转换或删除元素的子元素和后代。

[编辑] 我不确定我是否理解您的最新要求,因为输入似乎是一个完整的样式表,但作为想要的输出,您只显示了一个模板。所以假设你有输入

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="order">
        <cars>
            <car1 />
            <car2 />
        </cars>
    </xsl:template>
</xsl:stylesheet>

并且您想要转换xsl:template我将使用的模板正文中的 match 属性以及文字结果元素

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="xsl:template[@match = 'order']/@match">
    <xsl:attribute name="{name()}">
      <xsl:text>foo</xsl:text>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="xsl:template[@match = 'order']/cars">
    <xsl:copy>
      <xsl:apply-templates/>
      <TANK/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

这样我得到(用 Saxon 6.5.5 测试)结果

<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="foo">
        <cars>
            <car1/>
            <car2/>
        <TANK/></cars>
    </xsl:template>
</xsl:stylesheet>

希望这是您想要的(可能缺少适当的缩进)。

于 2012-05-17T10:31:08.403 回答