xml - 如何有条件地转换 XML 节点,而不忽略此条件之外的实例?

标签 xml xslt xpath-1.0


我正在改变一切 <p>标签并将这些节点重命名为 <Body_Text> ,条件是它们 <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>

最佳答案

不需要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">

导致选择此模板仅在作为 body 元素的后代的 p 元素上执行。所有其余节点均按身份规则“按原样”复制。

关于xml - 如何有条件地转换 XML 节点,而不忽略此条件之外的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11838285/

相关文章:

jquery - 使用 jquery 将 XML 属性转为 HTML 选择值

xslt - Aviarc REST Databroker 的 XSL 转换错误

xslt - XPath 1.0 : Finding count of nodes before a specified node

python - Python xpath中如何处理单引号和双引号

python-3.x - 如何从xpath提取元素标签中不存在的字段?

android - 更改布局缩进

python - 你如何使用 python 从 <abc>some Text</abc> 获取 "some Text"?

php - 如何使用 SimpleXML 检查元素是否存在?

xml - 如何使用嵌入式 XML 和 XSL 文件

xml - 编写有效的 XSLT