如何使用XSLT进行转换,以确定XML中的节点是否已被删除或重新创建?
我需要为下面的输入使用XSLT。此转换的目标是确定某个特定项目是否已被删除或重新创建 以下是输入示例: 第一个场景:如何使用XSLT进行转换,以确定XML中的节点是否已被删除或重新创建?,xml,xslt,Xml,Xslt,我需要为下面的输入使用XSLT。此转换的目标是确定某个特定项目是否已被删除或重新创建 以下是输入示例: 第一个场景: <root> <nodeA id="a"> <object id="1"> <item1 id="xx" method="create"> <attr> <color>yellow<
<root>
<nodeA id="a">
<object id="1">
<item1 id="xx" method="create">
<attr>
<color>yellow</color>
</attr>
</item1>
</object>
<object id="1">
<item1 id="xx" method="change">
<any>blah</any>
<attr>
<color>green</color>
</attr>
</item1>
<item1 id="xx" method="delete" />
</object>
<object id="2">
<item1 id="yy" method="create">
<any>aaa</any>
</item1>
</object>
</nodeA>
</root>
黄色的
废话
绿色
aaa
输出:
<root>
<nodeA id="a">
<object id="1">
</object>
<object id="1">
<item1 id="xx" method="delete" />
</object>
<object id="2">
<item1 id="yy" method="create">
<any>aaa</any>
</item1>
</object>
</nodeA>
</root>
<root>
<nodeB id="a">
<object id="2">
</object>
<object id="2">
<item2 id="xx" method="create">
<attr>
<color>pink</color>
</attr>
</item2>
<item2 id="xx" method="change">
<any>blah</any>
<attr>
<color>red</color>
</attr>
</item2>
</object>
<object id="3">
<item2 id="yy" method="create">
<any>ccc</any>
</item2>
</object>
</nodeB>
</root>
aaa
在上面的第一个场景中,我们看到item1已经被创建、更改和删除,这意味着它最终将被删除,这就是为什么我们只保留
,而忽略另一个
第二种情况:
<root>
<nodeB id="a">
<object id="2">
<item2 id="xx" method="create">
<attr>
<color>yellow</color>
</attr>
</item2>
</object>
<object id="2">
<item2 id="xx" method="change">
<attr>
<color>green</color>
</attr>
</item2>
<item2 id="xx" method="delete" /> <!-- because deletion occurs here, we disregard any previous node up until this delete -->
<item2 id="xx" method="create"> <!-- we keep this node and any node afterwards -->
<attr>
<color>pink</color>
</attr>
</item2>
<item2 id="xx" method="change">
<any>blah</any>
<attr>
<color>red</color>
</attr>
</item2>
</object>
<object id="3">
<item2 id="yy" method="create">
<any>ccc</any>
</item2>
</object>
</nodeB>
</root>
黄色的
绿色
粉红色
废话
红色
ccc
输出:
<root>
<nodeA id="a">
<object id="1">
</object>
<object id="1">
<item1 id="xx" method="delete" />
</object>
<object id="2">
<item1 id="yy" method="create">
<any>aaa</any>
</item1>
</object>
</nodeA>
</root>
<root>
<nodeB id="a">
<object id="2">
</object>
<object id="2">
<item2 id="xx" method="create">
<attr>
<color>pink</color>
</attr>
</item2>
<item2 id="xx" method="change">
<any>blah</any>
<attr>
<color>red</color>
</attr>
</item2>
</object>
<object id="3">
<item2 id="yy" method="create">
<any>ccc</any>
</item2>
</object>
</nodeB>
</root>
粉红色
废话
红色
ccc
在第二个场景中:我们看到item2在创建和更改之后,会被删除,然后重新创建和/或更改。这就是为什么我们忽略删除之前的所有节点,而只保留删除之后的所有节点
因此,总而言之:
- 创建/更改/../delete->将变为删除
- 创建/更改/../delete/create2/change2/..->create2/change2/
John我认为XSLT中有两条规则需要编码
- 如果您有一个具有“delete”方法的项,则只有在同一@id(和父@id)没有以下项时,您才能输出该项
- 如果您有一个方法不是“delete”的项,那么只有在同一@id(和父@id)没有后续“delete”项时才输出
<xsl:if test="not(following::*
[not(.//*[@id!=''])]
[@id=current()/@id]
[../@id = current()/../@id]
[generate-id(../..) = generate-id(current()/../..)])">
第二条规则是这样的
<xsl:if test="not(following::*
[not(.//*[@id!=''])]
[@method='delete']
[@id=current()/@id]
[../@id = current()/../@id]
[generate-id(../..) = generate-id(current()/../..)])">
注意:我通过查找没有任何具有@id属性的子元素的元素来识别“item”节点(即item1或item2)。还要注意,在这两种情况下,我假设这只发生在当前节点a/B元素中
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[not(.//*[@id!=''])][@method='delete']">
<xsl:if test="not(following::*[not(.//*[@id!=''])][@id=current()/@id][../@id = current()/../@id][generate-id(../..) = generate-id(current()/../..)])">
<xsl:call-template name="identity" />
</xsl:if>
</xsl:template>
<xsl:template match="*[not(.//*[@id!=''])][@method!='delete']">
<xsl:if test="not(following::*[not(.//*[@id!=''])][@method='delete'][@id=current()/@id][../@id = current()/../@id][generate-id(../..) = generate-id(current()/../..)])">
<xsl:call-template name="identity" />
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于第一个XML示例时,输出如下
<root>
<nodeA id="a">
<object id="1"/>
<object id="1">
<item1 id="xx" method="delete"/>
</object>
<object id="2">
<item1 id="yy" method="create">
<any>aaa</any>
</item1>
</object>
</nodeA>
</root>
<root>
<nodeB id="a">
<object id="2"/>
<object id="2">
<item2 id="xx" method="create">
<attr>
<color>pink</color>
</attr>
</item2>
<item2 id="xx" method="change">
<any>blah</any>
<attr>
<color>red</color>
</attr>
</item2>
</object>
<object id="3">
<item2 id="yy" method="create">
<any>ccc</any>
</item2>
</object>
</nodeB>
</root>
aaa
当应用于第二个XML示例(无注释)时,将输出以下内容
<root>
<nodeA id="a">
<object id="1"/>
<object id="1">
<item1 id="xx" method="delete"/>
</object>
<object id="2">
<item1 id="yy" method="create">
<any>aaa</any>
</item1>
</object>
</nodeA>
</root>
<root>
<nodeB id="a">
<object id="2"/>
<object id="2">
<item2 id="xx" method="create">
<attr>
<color>pink</color>
</attr>
</item2>
<item2 id="xx" method="change">
<any>blah</any>
<attr>
<color>red</color>
</attr>
</item2>
</object>
<object id="3">
<item2 id="yy" method="create">
<any>ccc</any>
</item2>
</object>
</nodeB>
</root>
粉红色
废话
红色
ccc
非常感谢。太完美了。