输入文件:
<root>
<sector>
<nodeA id="a">
<section id="i">
<item1 id="1" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="delete" />
</section>
</nodeA>
<nodeA id="b">
<cell id="ii">
<item2 id="2" method="create">
<otherchild>a</otherchild>
</item2>
</cell>
<cell id="ii">
<item2 id="2" method="delete" />
</cell>
</nodeA>
<nodeB id="i">
<cell id="ii">
<item3 id="1" method="create">
<child>b</child>
</item3>
</cell>
<cell id="ii">
<item3 id="1" method="delete" />
<item3 id="1" method="create">
<otherchild>a</otherchild>
</item3>
</cell>
</nodeB>
</sector>
</root>
预期输出:
<root>
<sector>
<nodeA id="a">
<section id="i">
</section>
</nodeA>
<nodeA id="b">
<cell id="ii">
</cell>
<cell id="ii">
</cell>
</nodeA>
<nodeB id="i">
<cell id="ii">
<item3 id="1" method="create"> <!-- this is not eliminated as it violates the rule by having create followed by delete and followed by create again -->
<child>b</child>
</item3>
</cell>
<cell id="ii">
<item3 id="1" method="delete" />
<item3 id="1" method="create">
<otherchild>a</otherchild>
</item3>
</cell>
</nodeB>
</sector>
</root>
我需要使用此规则消除xml中的节点:
method="create"
后跟一个method="delete"
节点将被删除<cell id="ii">
如何使用XSLT 1.0或2.0进行此转换?
谢谢。
答案 0 :(得分:1)
这是一种方法。您可以定义一个键,用于对要删除的项目进行分组。我认为你是通过元素的@id属性和两个父节点的@id属性进行分组
<xsl:key
name="items"
match="*[@method != '']" use="concat(@id, '|', ../@id, '|', ../../@id)" />
接下来,你可以有一个模板来匹配 @ method ='create'项目,其中键中有两个元素,另一个项目是 @ method ='delete “强>
<xsl:template match="*
[@method = 'create']
[count(key('items', concat(@id, '|', ../@id, '|', ../../@id))) = 2]
[key('items', concat(@id, '|', ../@id, '|', ../../@id))[@method = 'delete']]" />
您还需要一个模板,以类似的方式匹配其他 @ method ='delete'。
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="items" match="*[@method != '']" use="concat(@id, '|', ../@id, '|', ../../@id)" />
<xsl:template match="*[@method = 'create'][count(key('items', concat(@id, '|', ../@id, '|', ../../@id))) = 2][key('items', concat(@id, '|', ../@id, '|', ../../@id))[@method = 'delete']]" />
<xsl:template match="*[@method = 'delete'][count(key('items', concat(@id, '|', ../@id, '|', ../../@id))) = 2][key('items', concat(@id, '|', ../@id, '|', ../../@id))[@method = 'create']]" />
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<root>
<sector>
<nodeA id="a">
<section id="i"/>
</nodeA>
<nodeA id="b">
<cell id="ii"/>
<cell id="ii"/>
</nodeA>
<nodeB id="i">
<cell id="ii">
<item3 id="1" method="create">
<child>b</child>
</item3>
</cell>
<cell id="ii">
<item3 id="1" method="delete"/>
<item3 id="1" method="create">
<otherchild>a</otherchild>
</item3>
</cell>
</nodeB>
</sector>
</root>