当祖先标记(及其子标记)有空文本和特定属性值时,我尝试使用XSLT删除它们。我有XSLT来检查每个节点的text(),当它是空的并且祖先有属性deltaxml:deltaV2="A“时,我想删除祖先节点和子节点。
这里是我想要删除的xml标记(注意:祖先可以是任何东西,而不仅仅是'p')。在本例中,我希望删除最后一个p标记和子标记:
<body>
<p deltaxml:deltaV2="A=B">
<t>This is the same</t>
</p>
<p deltaxml:deltaV2="B">
<t>This is inserted</t>
</p>
<p deltaxml:deltaV2="A">
<t>This is deleted</t>
</p>
<p deltaxml:deltaV2="A">
<t> </t>
</p>
</body>下面是我到目前为止拥有的XSLT:
<xsl:template match="@* | * | processing-instruction() | comment()" mode="#all">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@*, node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="deltaV2" as="attribute()" select="ancestor::*[@deltaxml:deltaV2][1]/@deltaxml:deltaV2"/>
<xsl:variable name="text" select="."/>
<xsl:choose>
<xsl:when test="$deltaV2 eq 'A'">
<xsl:choose>
<xsl:when test="$text = ' '">
<!-- need to remove ancestor tags-->
</xsl:when>
<xsl:otherwise>
<xsl:element name="delete" namespace="{$root-ns}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$deltaV2 eq 'B'">
<xsl:element name="insert" namespace="{$root-ns}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
以下是所需的输出:
<body>
<p deltaxml:deltaV2="A=B">
<t>This is the same</t>
</p>
<p deltaxml:deltaV2="B">
<t><insert>This is inserted</insert></t>
</p>
<p deltaxml:deltaV2="A">
<t><delete>This is deleted</delete></t>
</p>
</body>我之所以需要这样做,是因为这些属性显示了XML的两个版本之间是否插入或删除了某个内容,但是如果存在一个空节点(即。(示例中的空t标记)我不想将其作为一个更改来跟踪,因为没有任何文本更改,而只是希望将其删除。当文本为空以便能够删除这些标记时,我需要放什么?
发布于 2016-08-03 19:40:22
我试图使用XSLT删除..。当标记有空文本和特定属性值时(以及它们的子标记)。
这样做的模板非常简单。
<xsl:template match="*[@deltaxml:deltaV2 = 'A' and normalize-space() = '']" />将其与身份转换一起使用。在这里阅读身份转换:http://www.dpawson.co.uk/xsl/sect2/identity.html (你最喜欢的搜索引擎会提供的其他无数例子)。
这里的这个问题还为您描述的同一个问题提供了一个规范的答案:How to remove elements from xml using xslt with stylesheet and xsltproc?
发布于 2016-08-03 21:02:02
不能在处理后代的模板中移除祖先。当样式表到达空的text()节点时,p祖先已经被处理并写入输出树-请参阅:https://www.w3.org/TR/xslt/#section-Processing-Model。
如果您将需求重声明为:删除满足这两种要求的任何元素(及其所有后代):
deltaxml:deltaV2的属性,其值为"A";然后,您可以将其实现为:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:deltaxml="http://example.com/deltaxml">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@deltaxml:deltaV2='A'][.//*[not(normalize-space())]]" />
</xsl:stylesheet>当然,您需要将deltaxml:前缀绑定到输入XML中使用的同一个命名空间URI,而不是像我在这里所做的那样任意绑定。
https://stackoverflow.com/questions/38751266
复制相似问题