Как сортировать узлы вместе с их следующими братьями и сестрами в XSLT? - PullRequest
0 голосов
/ 23 мая 2019

Я пытаюсь отсортировать файл XML по значению дочернего элемента с помощью XSLT.Элемент сортировки имеет следующий родственный элемент, который всегда должен быть после него.

XSLT, который я сделал до сих пор:

<xsl:template match="parent">
    <xsl:copy>
        <xsl:copy-of select="@*" />

        <xsl:copy-of select="*[not(self::city | self::cityNumber)]" />
        <xsl:for-each select="city">
            <xsl:sort select="text()" />
            <xsl:copy-of select="." />
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

Файл XML выглядит следующим образом:

<parent>
    <name>Bob</name>
    <name>Alice</name>
    <another-attribute>something</another-attribute>
    <city>B.111Kansas City</city>
    <cityNumber>1</cityNumber>
    <city>A.123Atlanta</city>
    <cityNumber>2</cityNumber>
</parent>

Я ожидаю выхода:

<parent>
   <name>Bob</name>
   <name>Alice</name>
   <another-attribute>something</another-attribute>
   <city>A.123Atlanta</city>
   <cityNumber>2</cityNumber>
   <city>B.111Kansas City</city>
   <cityNumber>1</cityNumber>
</parent>

Спасибо!

Ответы [ 2 ]

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

Если у вас есть несколько cityNumber, которые вы хотите отсортировать вместе с элементами city, вы можете использовать <xsl:for-each-group select="city | cityNumber" group-starting-with="city"> и отсортировать группы:

<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 indent="yes"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="parent">
      <xsl:copy>
          <xsl:apply-templates select="* except (city, cityNumber)"/>
          <xsl:for-each-group select="city | cityNumber" group-starting-with="city">
              <xsl:sort/>
              <xsl:apply-templates select="current-group()"/>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / gWvjQfL

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

Как насчет:

<xsl:template match="parent">
    <xsl:copy>
        <xsl:copy-of select="*[not(self::city or self::cityNumber)]" />
        <xsl:for-each select="city">
            <xsl:sort/>
            <xsl:copy-of select=". | following-sibling::cityNumber[1]" />
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...