0

被这个问题困扰了几天。

我正在尝试在对嵌套元素的属性进行排序时复制 xml 文件。我有什么我觉得应该工作

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:output method="xml" indent="yes" /> 
  <xsl:template match="node() | @*">
     <xsl:copy>
        <xsl:apply-templates select="node() | @*"/>
     </xsl:copy>      
</xsl:template>        
  <xsl:template match="PrProduct">
     <xsl:copy>
            <xsl:apply-templates select="node()|@* " >
            <xsl:sort select="@TEC"  order="descending" />
        </xsl:apply-templates>             
     </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

这是xml

<body>
<issueobject>
<page>
</page>
<prproduct TEC="TOR">
</prproduct>
<prproduct TEC="UVA">
<partPage>
</partPage>
</issueobject>
</body>

我认为问题在于,在我正在排序的元素的任一侧都有相同级别的元素,因为在玩耍时我可以对数据进行排序,但最终会丢失之前/之后的数据。

谢谢

4

2 回答 2

0

您的样式表所做的是根据(不存在的)属性的值对元素的内容进行排序。您需要的是一个与 , 在您的情况下 的父级匹配的模板,然后可以对元素进行排序。像这样的东西:PrProductTECPrProductissueobjectPrProduct

<xsl:template match="issueobject">
    <xsl:copy>
        <xsl:apply-templates select="PrProduct[1]/preceding-sibling::*"/>
        <xsl:apply-templates select="PrProduct">
            <xsl:sort select="@TEC" order="descending"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="PrProduct[1]/following-sibling::*[not(self::PrProduct)]"/>
    </xsl:copy>
</xsl:template>

(请注意,此示例忽略 的文本子级issueobject。)

于 2013-04-08T20:48:05.227 回答
0

您当前的模板正在尝试对prproduct元素的子节点进行排序,并找到裸露的橱柜。您可以做的是将模板更改为仅匹配第一个prproduct元素,然后对该元素和以下prproduct兄弟元素进行排序

<xsl:template match="prproduct[1]">
     <xsl:for-each select="self::*|following-sibling::prproduct">
        <xsl:sort select="@TEC" order="descending"/>
        <!-- Copy element -->
     </xsl:for-each>
</xsl:template>

除此之外,您只需要一个模板来阻止其他prproduct元素被输出两次

<xsl:template match="prproduct"/>

这是完整的 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

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

   <xsl:template match="prproduct[1]">
       <xsl:for-each select="self::*|following-sibling::prproduct">
         <xsl:sort select="@TEC" order="descending"/>
         <xsl:call-template name="identity"/>
      </xsl:for-each>
   </xsl:template>

   <xsl:template match="prproduct"/>
</xsl:stylesheet>

当应用于您的 XML 时,将输出以下内容

<body>
   <issueobject>
       <page></page>
       <prproduct TEC="UVA"></prproduct>
       <prproduct TEC="TOR"></prproduct>
       <partPage></partPage>
   </issueobject>
</body>

注意命名模板的使用,以避免身份模板的重复编码。

于 2013-04-08T21:00:11.710 回答