Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用XSLT进行转换,以确定XML中的节点是否已被删除或重新创建?_Xml_Xslt - Fatal编程技术网

如何使用XSLT进行转换,以确定XML中的节点是否已被删除或重新创建?

如何使用XSLT进行转换,以确定XML中的节点是否已被删除或重新创建?,xml,xslt,Xml,Xslt,我需要为下面的输入使用XSLT。此转换的目标是确定某个特定项目是否已被删除或重新创建 以下是输入示例: 第一个场景: <root> <nodeA id="a"> <object id="1"> <item1 id="xx" method="create"> <attr> <color>yellow<

我需要为下面的输入使用XSLT。此转换的目标是确定某个特定项目是否已被删除或重新创建

以下是输入示例: 第一个场景:

<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”节点(即item1item2)。还要注意,在这两种情况下,我假设这只发生在当前节点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

非常感谢。太完美了。