在xslt转换中保留节点

时间:2012-09-13 13:59:33

标签: php xml xslt xpath

<root>
<tag>
  <form>
   some html form will be here
  </form>

</tag>
<tag>
  some visible data
</tag>

XSLT

<xsl:template match="tag">
    <div id="page-base">
      <xsl:apply-templates />
    </div>
  </xsl:template>

产生

<div id="page-base">

</div>
<div id="page-base">
 some visible data
</div>

所需的输出

<div id="page-base">
 <form>
   some html form will be here
  </form>
</div>
<div id="page-base">
 some visible data
</div>

修改

如果tag嵌套在应用了模板规则的tag元素中,它会将标记替换为模板,并复制模板不匹配的其他元素,该怎么办?请看例子。 tag可能是aribtrary嵌套

<root>
        <tag>
          <form>
           some html form will be here
          </form>
          <tag>
            arbitrary nested tags
          </tag>    
        </tag>
        <tag>
          some visible data
        </tag>
</root>

预期结果

 <div id="page-base">
     <form>
       some html form will be here
      </form>
      <div id="page-base">
       arbitrary nested tags  
      </div>
  </div>
  <div id="page-base">
     some visible data
  </div>

2 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="tag">
  <div id="page-base">
    <xsl:copy-of select="node()"/>
  </div>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<root>
    <tag>
        <form>
   some html form will be here
        </form>
    </tag>
    <tag>
  some visible data
    </tag>
</root>

会产生想要的正确结果:

<div id="page-base">
   <form>
   some html form will be here
        </form>
</div>
<div id="page-base">
  some visible data
    </div>

<强>解释

您的代码缺少复制匹配的tag元素正文的内容。

这个“东西”是 xsl:copy-of 指令。


<强>更新

OP已经改变了他的问题,这需要一个不同的解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

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

 <xsl:template match="tag">
  <div id="page-base">
    <xsl:apply-templates/>
  </div>
 </xsl:template>
</xsl:stylesheet>

在新提供的XML文档上应用此转换时:

<div id="page-base">
   <form>
           some html form will be here
          </form>
   <div id="page-base">
            arbitrary nested tags
          </div>
</div>
<div id="page-base">
          some visible data
        </div>

答案 1 :(得分:1)

添加copy rule

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

这将简单地复制任何与更具描述性的模板不匹配的节点。由于匹配规则的特殊性,除非您调整优先级,否则其他规则将优先,在这种情况下,您应该将此规则指定为比其他任何规则低priority

如果您只想复制树的某些部分,则应为其添加单独的模式,无论何时调用应用该模板,都必须指定该模式。

<xsl:template match="@*|node()" mode="copy">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" mode="copy"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="tag">
  <div id="page-base">
    <xsl:apply-templates mode="copy"/>
  </div>
</xsl:template>

如果您使用的是XSLT 2.0,则还可以使用copy-of进行深层复制。但上述方法仍然更灵活,因为它允许您从副本中省略或转换某些节点。