我正在改变一切 <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/