如何有条件地转换XML节点,而不省略其超出此条件的实例?

时间:2012-08-07 01:50:23

标签: xml xslt xpath-1.0


我正在转换所有<p>代码并将这些节点重命名为<Body_Text>,条件是它们在<{em> <body>元素内(使用xsl:if) 。

我的代码 这样做,但是它省略了<p>元素之外的所有<body>元素,我想要它去做。

<小时/> 这是要转换的XML:

<root>
<p>asdf</p>
<body>
<p>asdfasdf</p>
<p>asdfasdf</p>
</body>
<footer>
<p>asdf</p>
</footer>
</root>


......这是XSL:

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

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

    <!-- Body_Text -->
    <xsl:template match="p">
      <xsl:if test="parent::body">
        <Body_Text>
          <xsl:apply-templates select="@*|node()"/>
        </Body_Text>
      </xsl:if>
    </xsl:template>

</xsl:stylesheet>


...这里是不受欢迎的结果(省略<p>元素之外的所有<body>元素,我希望它这样做:

<root>
<body>
<Body_Text>asdfasdf</Body_Text>
<Body_Text>asdfasdf</Body_Text>
</body>
<footer/>
</root>


这在http://xslt.online-toolz.com/tools/xslt-transformation.php进行了测试。

<小时/> 这是理想的结果,我

<root>
<p>asdf</p>
<body>
<Body_Text>asdfasdf</Body_Text>
<Body_Text>asdfasdf</Body_Text>
</body>
<footer>
<p>asdf</p>
</footer>
</root>

1 个答案:

答案 0 :(得分:2)

不需要xsl:if - 只需指定正确的模板模式。

此转化:

<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="body//p">
  <Body_Text><xsl:apply-templates select="@*|node()"/></Body_Text>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<root>
    <p>asdf</p>
    <body>
        <p>asdfasdf</p>
        <p>asdfasdf</p>
    </body>
    <footer>
        <p>asdf</p>
    </footer>
</root>

会产生想要的正确结果:

<root>
   <p>asdf</p>
   <body>
      <Body_Text>asdfasdf</Body_Text>
      <Body_Text>asdfasdf</Body_Text>
   </body>
   <footer>
      <p>asdf</p>
   </footer>
</root>

<强>解释

模板模式:

 <xsl:template match="body//p">

导致选择此模板仅在p元素后代的body元素上执行。所有其余节点都按照标识规则“按原样”复制。