Xml 如何使用XSLT修复连续节点出现时的这种消除?
我有这个输入文件:Xml 如何使用XSLT修复连续节点出现时的这种消除?,xml,xslt,Xml,Xslt,我有这个输入文件: <myroot> <list id="xxx"> <node id="a"> <section id="i"> <item1 id="a0" method="start"> <somechild>a</somechild> </item1
<myroot>
<list id="xxx">
<node id="a">
<section id="i">
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
<item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate -->
<somechild>a</somechild>
</item1>
<item1 id="a0" method="stop"/>
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
<section id="i">
<item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate -->
<somechild>a</somechild>
</item1>
<item1 id="a0" method="stop"/>
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
<item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate -->
<somechild>a</somechild>
</item1>
</section>
</node>
</list>
</myroot>
A.
A.
A.
A.
A.
A.
以及我的输出:
<myroot>
<list id="xxx">
<node id="a">
<section id="i">
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
<item1 id="a0" method="stop"/>
</section>
<section id="i" />
</node>
</list>
</myroot>
**While the expected output should be:**
<myroot>
<list id="xxx">
<node id="a">
<section id="i">
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
<item1 id="a0" method="stop"/>
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
<section id="i">
<item1 id="a0" method="stop"/>
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
</node>
</list>
</myroot>
A.
**而预期产出应为:**
A.
A.
A.
XSLT文件:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="@* | node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*/*">
<xsl:copy>
<xsl:variable name="first-in-group" as="element()*">
<xsl:for-each-group select="*" group-by="concat(node-name(.), '|', @id,'|', @method)">
<xsl:for-each-group select="current-group()/*" group-by="concat(@id, '|', @method)">
<xsl:sequence
select="for $pos in 1 to count(current-group())
return current-group()[$pos]
[every $item
in subsequence(current-group(), 1, $pos - 1)
satisfies not(deep-equal($item, current-group()[$pos]))] "/>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:variable>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates>
<xsl:with-param name="first-in-group" select="$first-in-group" tunnel="yes"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="/*/*/*/*/*">
<xsl:param name="first-in-group" tunnel="yes"/>
<xsl:if test="$first-in-group intersect .">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
另一种情况:
<myroot>
<list id="xxx">
<node id="a">
<section id="i">
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
<section id="i">
<item1 id="a1" method="start">
<somechild>a</somechild>
</item1>
<item1 id="a0" method="start"> <!-- this one is successive from the previous, because the previous node has id of 'a1', so we eliminate -->
<somechild>a</somechild>
</item1>
<item1 id="a0" method="start"> <!-- this one is successive from the previous so we eliminate -->
<somechild>a</somechild>
</item1>
</section>
</node>
</list>
</myroot>
A.
A.
A.
A.
预期产出:
<myroot>
<list id="xxx">
<node id="a">
<section id="i">
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
<section id="i">
<item1 id="a1" method="start">
<somechild>a</somechild>
</item1>
</section>
</node>
</list>
</myroot>
A.
A.
其思想是用相同的方法删除连续的节点。在示例中:
- 启动/启动/停止/启动/启动-->启动/停止/启动
约翰也许我遗漏了什么,但看起来你把事情复杂化了。您应该能够匹配/剥离任何等于相同名称的前一个元素的元素 XSLT2.0
<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()][1])]"/>
</xsl:stylesheet>
XML输出(使用上面更新的XML)
A.
A.
A.
修复了已删除的
嗨,原来删除只对第一个
零件有效。您有什么建议可以让您的解决方案在第二个
上运行吗。请查看我的扩展输入更新。非常感谢。@John-我不知道你的意思。使用扩展输入,我可以准确地得到您在下列出的内容,而预期的输出应该是:
。如果预期的输出与您的问题不同,请更新它。@John-另外,如果我接受您的扩展输入并手动删除您标记的应该删除的项目,这也与我在回答中得到的样式表的输出相匹配。对不起,我给出了错误的输出。我已经添加了其他场景,所以基本上连续的将考虑<代码>相同的元素名称、相同的ID和相同的方法< /代码>。非常感谢你的帮助。
<myroot>
<list id="xxx">
<node id="a">
<section id="i">
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
<item1 id="a0" method="stop"/>
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
<section id="i">
<item1 id="a0" method="stop"/>
<item1 id="a0" method="start">
<somechild>a</somechild>
</item1>
</section>
</node>
</list>
</myroot>