使用其周围的其他元素对xsl中的属性进行排序

时间:2013-04-08 18:03:16

标签: xml xslt

现在被这个问题困扰了几天。

我正在尝试在对嵌套元素的属性进行排序时复制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>

我认为问题在于,我在排序的元素两侧的同一级别的元素我在播放时可以对数据进行排序,但最终会在之后/之前丢失数据。

由于

2 个答案:

答案 0 :(得分:0)

样式表的作用是按{不存在的} PrProduct属性的值对TEC元素的内容进行排序。您需要的是一个匹配PrProduct的模板,在您的情况下issueobject,然后可以对PrProduct元素进行排序。像这样:

<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的文本子项。)

答案 1 :(得分: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>

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