XSLT сортирует дочерние узлы под разными родительскими узлами - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь отсортировать xml с помощью xslt, но проблема в том, что мой код сортирует элементы только под конкретным узлом, вот пример xml:

<region name="Germany">
    <company name="Mercedes" rank="2" />
    <company name="BMW" rank="3" />
</region>
<region name="Japan">
    <company name="Toyota" rank="1" />
    <company name="Mazda" rank="4" />
</region>

Я попробовал выполнить следующее, но этого не произошлоработа

<xsl:template match="region">
    <Companies>
        <xsl:for-each select="company">
            <xsl:sort select="@rank" />
            <xsl:call-template name="companies">
        </xsl:for-each>
    </Companies>
</xsl:template>

<xsl:template name="companies">
     <Company>
        <xsl:value-of select="@name" />
     </Company>
</xsl:template>

вывод должен быть:

<Companies>
    <Company>Toyota</Company>
    <Company>Mercedes</Company>
    <Company>BMW</Company>
    <Company>Mazda</Company>
</Companies>

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Вы не показали ни одного элемента контейнера для этих элементов region, но, предполагая, что они находятся внутри одного общего контейнера, напишите шаблон, соответствующий этому контейнеру (например, с именем root в примере кода ниже), а затем я бы просто предложилприменить шаблоны к внукам company с включенным xsl:sort на основе атрибута rank.

Затем добавьте шаблон, преобразовывающий из company элементов ввода на основе атрибутов в элемент на основе значений, и все готово:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

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

  <xsl:template match="root">
      <Companies>
          <xsl:apply-templates select="region/company">
              <xsl:sort select="xs:integer(@rank)"/>
          </xsl:apply-templates>
      </Companies>
  </xsl:template>

  <xsl:template match="company">
      <xsl:copy>
          <xsl:value-of select="@name"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net /94rmq6B

Совпадение для каждого region, кажется, не имеет смысла, если вы хотите обработать их все вместе отсортированным образом.

1 голос
/ 14 мая 2019

По выводу кажется, что вы хотите отсортировать по рангу, а не по имени.

Относительно сортировки, происходящей с узлом, поскольку ваш шаблон работает для каждого региона, и поэтому сортировка выполняется для узлов компании в пределахобласть, край.Вы можете запустить шаблон для родителя региона, а затем перебрать элементы и отсортировать по имени.Вот шаблон с совпадающим выводом.

<xsl:template match="*[region]">
    <Companies>
        <xsl:for-each select="region/company">
            <xsl:sort select="@rank" />
            <xsl:call-template name="companies" />
        </xsl:for-each>
    </Companies>
</xsl:template>

<xsl:template name="companies">
     <Company>
        <xsl:value-of select="@name" />
     </Company>
</xsl:template> 
...