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
Xml XSLT:排序路径跟踪_Xml_Xslt - Fatal编程技术网

Xml XSLT:排序路径跟踪

Xml XSLT:排序路径跟踪,xml,xslt,Xml,Xslt,我有以下意见: <articles> <item name="B"> <item name="Bb"> <item name="Bbb"/> <item name="Abb"/> </item> <item name="Ab"> <item name="Bab"/> <item name="Aab"/> &

我有以下意见:

<articles>
  <item name="B">
    <item name="Bb">
      <item name="Bbb"/>
      <item name="Abb"/>
    </item>
    <item name="Ab">
      <item name="Bab"/>
      <item name="Aab"/>
    </item>
  </item>
  <item name="A">
    <item name="Ba">
      <item name="Bba"/>
      <item name="Aba"/>
    </item>
    <item name="Aa">
      <item name="Baa"/>
      <item name="Aaa"/>
    </item>
  </item>
  <item name="D"/>
  <item name="C">
    <item name="Ac"/>
  </item>
</articles>
也就是说,每个路径都应明确,并在每个级别上进行排序。我有下面的XSLT,它生成路径,但除了第一级之外,我无法计算排序

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

  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="articles">
    <xsl:apply-templates select="//item[not(item)]">
      <xsl:sort select="ancestor-or-self::item[parent::articles]/@name"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="item">
    <xsl:for-each select="ancestor-or-self::item">
      <xsl:value-of select="@name"/>
      <xsl:choose>
        <xsl:when test="not(item)">
          <xsl:text>&#xA;</xsl:text>
        </xsl:when>
        <xsl:otherwise>-</xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>


;
-

恐怕我目前的做法是走不通的。想法?

不太好,但是下面的内容是针对3个项目的深度进行的,并且每增加一个级别都需要额外的排序。我相信一位大师能够更一般地做到这一点:)



;
-

请注意,XSLT2.0解决方案(第二部分)要短得多、简单得多


I.这里是一个简单的两遍解决方案

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
    <xsl:apply-templates/>
  </xsl:variable>

  <xsl:for-each select="ext:node-set($vrtfPass1)/*">
   <xsl:sort/>
   <xsl:value-of select="concat(., '&#xA;')"/>
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="item[not(item)]">
     <x>
      <xsl:for-each select="ancestor-or-self::item">
       <xsl:if test="not(position() = 1)">-</xsl:if>
       <xsl:value-of select="@name"/>
      </xsl:for-each>
     </x>
 </xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

 <xsl:template match="/">
     <xsl:for-each-group select="//item[not(item)]"
     group-by="string-join(ancestor-or-self::item/@name, '-')">
      <xsl:sort select="current-grouping-key()"/>
      <xsl:sequence select="current-grouping-key(), '&#xA;'"/>
     </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>
注意事项:这是一个通用解决方案,可正确处理
元素的任何嵌套

说明

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:variable name="vrtfPass1">
    <xsl:apply-templates/>
  </xsl:variable>

  <xsl:for-each select="ext:node-set($vrtfPass1)/*">
   <xsl:sort/>
   <xsl:value-of select="concat(., '&#xA;')"/>
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="item[not(item)]">
     <x>
      <xsl:for-each select="ancestor-or-self::item">
       <xsl:if test="not(position() = 1)">-</xsl:if>
       <xsl:value-of select="@name"/>
      </xsl:for-each>
     </x>
 </xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

 <xsl:template match="/">
     <xsl:for-each-group select="//item[not(item)]"
     group-by="string-join(ancestor-or-self::item/@name, '-')">
      <xsl:sort select="current-grouping-key()"/>
      <xsl:sequence select="current-grouping-key(), '&#xA;'"/>
     </xsl:for-each-group>
 </xsl:template>
</xsl:stylesheet>
  • 我们执行两次转换

  • 第一次通过的结果是:

    <x xmlns:ext="http://exslt.org/common">B-Bb-Bbb</x>
    <x xmlns:ext="http://exslt.org/common">B-Bb-Abb</x>
    <x xmlns:ext="http://exslt.org/common">B-Ab-Bab</x>
    <x xmlns:ext="http://exslt.org/common">B-Ab-Aab</x>
    <x xmlns:ext="http://exslt.org/common">A-Ba-Bba</x>
    <x xmlns:ext="http://exslt.org/common">A-Ba-Aba</x>
    <x xmlns:ext="http://exslt.org/common">A-Aa-Baa</x>
    <x xmlns:ext="http://exslt.org/common">A-Aa-Aaa</x>
    <x xmlns:ext="http://exslt.org/common">D</x>
    <x xmlns:ext="http://exslt.org/common">C-Ac</x>
    
    <x xmlns:ext="http://exslt.org/common">B-Bb-Bbb</x>
    <x xmlns:ext="http://exslt.org/common">B-Bb-Abb</x>
    <x xmlns:ext="http://exslt.org/common">B-Ab-Bab</x>
    <x xmlns:ext="http://exslt.org/common">B-Ab-Aab</x>
    <x xmlns:ext="http://exslt.org/common">A-Ba-Bba</x>
    <x xmlns:ext="http://exslt.org/common">A-Ba-Aba</x>
    <x xmlns:ext="http://exslt.org/common">A-Aa-Baa</x>
    <x xmlns:ext="http://exslt.org/common">A-Aa-Aaa</x>
    <x xmlns:ext="http://exslt.org/common">D</x>
    <x xmlns:ext="http://exslt.org/common">C-Ac</x>
    
    <xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>
    
     <xsl:template match="/">
         <xsl:for-each-group select="//item[not(item)]"
         group-by="string-join(ancestor-or-self::item/@name, '-')">
          <xsl:sort select="current-grouping-key()"/>
          <xsl:sequence select="current-grouping-key(), '&#xA;'"/>
         </xsl:for-each-group>
     </xsl:template>
    </xsl:stylesheet>