XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[*][deep-equal(.,preceding::*[name()=current()/name()][@id=current()/@id][1])]"/>
</xsl:stylesheet>
应用于我的输入时:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
给我正确的输出:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
* 但问题是当我有另一个nodeA
具有不同的id
时,它会将这两个节点视为一个*
第二个输入示例:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
我的输出:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"><!-- third consecutive create, BUT children have different value , so we don't remove this --><somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"><!-- third consecutive create, BUT children have different value , so we don't remove this --><somechild>bbb</somechild>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
预期输出应为:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
我应该在XSLT文件上添加什么内容,使其适用于两个或更多节点父nodeA
或nodeB
等。
目标是使用successive duplicate
删除节点
相同的元素名称item1
item2
等,相同的id
和相同的method
。
XML节点后跟其他具有完全same element name
,same
id
,same method
和same children
的节点将被视为重复。
如果被比较的两个节点没有共享相同的'nodeA'级别 节点,那么它们不应被视为要删除的重复项
由于 约翰
答案 0 :(得分:3)
此转化:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<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=
"section/*
[for $current in .,
$curNodeAnc in $current/ancestor::*[starts-with(name(), 'node')][1]
return
some $preceding in $current/preceding::*
satisfies
$preceding/parent::section
and
$curNodeAnc is $preceding/ancestor::*[starts-with(name(), 'node')][1]
and
deep-equal($current, $preceding)
]
"/>
</xsl:stylesheet>
应用于提供的XML文档:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
产生了完全想要的结果,虽然要求定义严重并且实际上与想要的结果相矛盾 - 显然John在这方面有很大的改进空间:
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"><!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"><!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
答案 1 :(得分:1)
将此文档作为输入文档....
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"> <!-- second consecutive create, we will remove this -->
<somechild>a</somechild>
</item1>
<item1 id="0" method="create"> <!-- third consecutive create, BUT children have different value , so we don't remove this -->
<somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
<item1 id="0" method="change"> <!-- second consecutive create, we will remove this -->
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
..和这个样式表......
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[*]
[deep-equal(.,
preceding::*[name()=current()/name()]
[@id = current()/@id]
[../../@id = current()/../../@id]
[1])]" />
</xsl:stylesheet>
...产生规定的所需输出......
<?xml version="1.0" encoding="UTF-8"?>
<myroot>
<nodeA id="a">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"><!-- third consecutive create, BUT children have different value , so we don't remove this --><somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
<nodeA id="b">
<section id="i">
<item1 id="0" method="create">
<somechild>a</somechild>
</item1>
<item1 id="1" method="create">
<otherchild>a</otherchild>
</item1>
</section>
<section id="i">
<item1 id="0" method="create"><!-- third consecutive create, BUT children have different value , so we don't remove this --><somechild>bbb</somechild>
</item1>
<item1 id="3" method="create">
<other>xx</other>
</item1>
<item1 id="0" method="change">
<otherchild>a</otherchild>
</item1>
</section>
</nodeA>
</myroot>
注意,您可以使用这种稍微变化的样式表来帮助验证。它不是删除节点,而是通过插入节点来注释它们。查看它的输出有助于可视化正在发生的事情。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[*]
[deep-equal(.,
preceding::*[name()=current()/name()]
[@id = current()/@id]
[../../@id = current()/../../@id]
[1])]" >
<xsl:copy>
<xsl:apply-templates select="@*" />
<removed>
<xsl:value-of select="'Parent of this node will be REMOVED.'" />
<xsl:value-of select="../../@id" />
</removed>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>