Xslt XSL转换中的节点顺序

Xslt XSL转换中的节点顺序,xslt,xslt-1.0,Xslt,Xslt 1.0,我有一个如下所示的xml: <?xml version="1.0" encoding="UTF-8"?> <Object> <Data type="plan" name="testAom" id="10"> <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-1" operation="create" > <p name="Active">1</p&g

我有一个如下所示的xml:

<?xml version="1.0" encoding="UTF-8"?>
<Object>
<Data type="plan" name="testAom" id="10">

    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-1" operation="create" >
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>

    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-1/E-1" operation="create">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>

    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="update">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>

    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="update">
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>
</Data>
</Object>

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

0

10

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

这里输入源文件的顺序不能保证。但是在XSL转换后的输出中,我要求输出按一定顺序进行

以下是XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="@*|node()">
<xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="obj[@class = 'D' ]">
<xsl:variable name="item" select="."/>
<xsl:choose>
    <xsl:when test="$item/@operation='update'">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="operation">delete</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="operation">create</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:when>
    <xsl:otherwise>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="operation">NEW_create</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="obj[@class = 'E' ]">
<xsl:variable name="childitem" select="."/>
<xsl:choose>
    <xsl:when test="$childitem/@operation='update'">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="operation">delete</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="operation">create</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:when>
    <xsl:otherwise>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:attribute name="operation">NEW_create</xsl:attribute>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:otherwise>
</xsl:choose>
</xsl:template>         
</xsl:stylesheet>

删除
创造
新建
删除
创造
新建
我得到的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<Object>
<Data type="plan" name="testAom" id="10">

    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-1" operation="NEW_create">
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>

    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-1/E-1" operation="NEW_create">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>

    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="delete">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>
    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="create">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>

    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="delete">
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>
    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="create">
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>
</Data>
</Object>

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

0

10

0

10

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

在这里,当操作属性为“更新”时,我需要执行删除和创建操作

上面的节点基于属性distName具有父子关系,即a-1/B-1/C-1/D-1a-1/B-1/C-1/D-1/E-1的父节点。 要使更新操作正常工作,我需要先创建和删除父级,然后再执行子级删除和始终创建

如何在不考虑输入源xml文件顺序的情况下实现这一点??

即,具有class属性D的obj节点应排在E之前

预期输出XML:

<?xml version="1.0"?>
<Object>
<Data type="plan" name="testAom" id="10">
<obj class="D" version="1.0" distName="A-1/B-1/C-1/D-1" operation="NEW_create">
<p name="Active">1</p>
<p name="Type">CPU</p>
<p name="StDate">2013-07-27T00:00:00+00:00</p>
<p name="StpDate">2013-07-29T00:00:00+00:00</p>
</obj>
<obj class="E" version="1.0" distName="A-1/B-1/C-1/D-1/E-1" operation="NEW_create">
<p name="dayOfWeek">0</p>
<p name="interval">10</p>
</obj>
<obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="delete">
<p name="Active">1</p>
<p name="Type">CPU</p>
<p name="StDate">2013-07-27T00:00:00+00:00</p>
<p name="StpDate">2013-07-29T00:00:00+00:00</p>
</obj><obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="create">
<p name="Active">1</p>
<p name="Type">CPU</p>
<p name="StDate">2013-07-27T00:00:00+00:00</p>
<p name="StpDate">2013-07-29T00:00:00+00:00</p>
</obj>
<obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="delete">
<p name="dayOfWeek">0</p>
<p name="interval">10</p>
</obj><obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="create">
<p name="dayOfWeek">0</p>
<p name="interval">10</p>
</obj>
</Data>
</Object>

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

0

10


我可能在您的需求中遗漏了一些东西,但如果没有,那么更新就是简单的删除和创建,可以在单个模板中完成。我把解决方案集中在行动上,而不是课堂上。我认为我的样式表完全可以生成您要求生成的内容,但它可能没有实现您想要的内容。我希望有帮助

t:\ftemp>type objects.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Object>
<Data type="plan" name="testAom" id="10">

    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-1" operation="create" >
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>

    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-1/E-1" operation="create">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>

    <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="update">
        <p name="dayOfWeek">0</p>
        <p name="interval">10</p>
    </obj>

    <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="update">
        <p name="Active">1</p>
        <p name="Type">CPU</p>
        <p name="StDate">2013-07-27T00:00:00+00:00</p>
        <p name="StpDate">2013-07-29T00:00:00+00:00</p>
    </obj>
</Data>
</Object>
t:\ftemp>call xslt objects.xml objects.xsl 
<?xml version="1.0" encoding="utf-8"?>
<Object>

   <Data type="plan" name="testAom" id="10">
      <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-1" operation="New_create">
         <p name="Active">1</p>
         <p name="Type">CPU</p>
         <p name="StDate">2013-07-27T00:00:00+00:00</p>
         <p name="StpDate">2013-07-29T00:00:00+00:00</p>
      </obj>
      <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-1/E-1" operation="New_create">
         <p name="dayOfWeek">0</p>
         <p name="interval">10</p>
      </obj>
      <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="delete">
         <p name="Active">1</p>
         <p name="Type">CPU</p>
         <p name="StDate">2013-07-27T00:00:00+00:00</p>
         <p name="StpDate">2013-07-29T00:00:00+00:00</p>
      </obj>
      <obj class="D" version="1.0" distName="A-1/B-1/C-1/D-2" operation="create">
         <p name="Active">1</p>
         <p name="Type">CPU</p>
         <p name="StDate">2013-07-27T00:00:00+00:00</p>
         <p name="StpDate">2013-07-29T00:00:00+00:00</p>
      </obj>
      <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="delete">
         <p name="dayOfWeek">0</p>
         <p name="interval">10</p>
      </obj>
      <obj class="E" version="1.0" distName="A-1/B-1/C-1/D-2/E-1" operation="create">
         <p name="dayOfWeek">0</p>
         <p name="interval">10</p>
      </obj>
   </Data>

</Object>
t:\ftemp>type objects.xsl 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="Object/Data">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <!--results are in distName order-->
    <xsl:apply-templates select="obj">
      <xsl:sort select="@distName"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<!--for creation, only the attribute changes, nothing else-->
<xsl:template match="obj[@operation='create']">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:attribute name="operation">New_create</xsl:attribute>
    <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

<!--remove those marked for deletion-->
<xsl:template match="obj[@operation='delete']"/>

<!--remove and recreate those marked for update-->
<xsl:template match="obj[@operation='update']">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:attribute name="operation">delete</xsl:attribute>
    <xsl:apply-templates select="*"/>
  </xsl:copy>
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:attribute name="operation">create</xsl:attribute>
    <xsl:apply-templates select="*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="@*|node()"><!--identity for all other nodes-->
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>rem Done! 
t:\ftemp>type objects.xml

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

0

10

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

t:\ftemp>调用xslt objects.xml objects.xsl

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

1

CPU

2013-07-27T00:00:00+00:00

2013-07-29T00:00:00+00:00

0

10

0

10

t:\ftemp>type objects.xsl 新建 删除 创造 t:\ftemp>rem完成!
您给了我们一个不起作用的样式表及其不理想的结果,但您没有向我们展示您给定的示例输入的理想结果。嗨,Ken,我已经更正了我的问题,并更新了所需的理想结果。您是否需要处理a、B和C的类属性?是的。。。。可以有任何类…嗨,Ken,如果xml与xmlns=“xyz.xsd”关联,如何处理上述xsl。。我当时不知道如何使用它?这与任何附加到输入元素的名称空间没有什么不同,只需使用通常的方法将名称空间的前缀添加到样式表中的元素名称中即可。