xsl для заказа подузлов xml - PullRequest
       0

xsl для заказа подузлов xml

2 голосов
/ 02 октября 2011

Вот пример xml

<Data version="2.0">
   <Group>
        <Item>3</Item>
        <Item>1</Item>
        <Item>2</Item>
   </Group>
   <Group>
        <Item>7</Item>
        <Item>5</Item>
   </Group>
</Data>

А для упорядочения узлов в значении Группировка по элементу я попытался использовать следующий xsl:

  <xsl:template match="/Data">

    <xsl:apply-templates select="Group">
      <xsl:sort select="Item" />
    </xsl:apply-templates>

  </xsl:template>

Но получить только значения, даже без сортировки:

    3
    1
    2

    7
    5

Итак, вопросы: 1. почему сортировка не работает 2. Как сохранить все узлы и сохранить структуру XML?

Ответы [ 2 ]

4 голосов
/ 02 октября 2011

Это то, что вы хотите:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Group">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="Item">
                <xsl:sort select="text()" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>    
</xsl:stylesheet>

Первый шаблон - это «шаблон идентификации» (Google it), который копирует входные данные в выходные данные без изменений.Затем для узла Group мы копируем его в вывод (<xsl:copy>), копируем его атрибуты, затем копируем вложенные узлы Item после их сортировки.Они копируются, потому что внутренний <xsl:apply-templates select="Item"> заканчивается использованием шаблона Identity, поскольку для узлов Item не существует более конкретного шаблона.

Обратите внимание, что если Group узлы могут содержать другие элементы, кроме Item, выЯ должен убедиться, что он тоже скопирован.Шаблон выше отбросит их.

2 голосов
/ 02 октября 2011

@ Ответ Джима в основном правильный.

Однако применяется к чуть более реалистичному XML-документу, такому как :

<Data version="2.0">
   <Group>
        <Item>3</Item>
        <Item>1</Item>
        <Item>10</Item>
        <Item>2</Item>
   </Group>
   <Group>
        <Item>7</Item>
        <Item>5</Item>
   </Group>
</Data>

полученный результат явно не то, что вы хотите (10 предшествует 2 и 3):

<?xml version="1.0" encoding="utf-8"?>
<Data version="2.0">

   <Group>
      <Item>1</Item>
      <Item>10</Item>
      <Item>2</Item>
      <Item>3</Item>
   </Group>

   <Group>
      <Item>5</Item>
      <Item>7</Item>
   </Group>

</Data>

Вот правильное решение (это такженемного короче):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="Group">
  <Group>
   <xsl:apply-templates select="*">
    <xsl:sort data-type="number"/>
   </xsl:apply-templates>
  </Group>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к тому же XML-документу (см. выше), будет получен требуемый, правильный результат :

<Data version="2.0">
   <Group>
      <Item>1</Item>
      <Item>2</Item>
      <Item>3</Item>
      <Item>10</Item>
   </Group>
   <Group>
      <Item>5</Item>
      <Item>7</Item>
   </Group>
</Data>

Объяснение : Использование атрибута data-type <xsl:sort>, чтобы указать, что значение ключей сортировки следует рассматривать как число, а не как (по умолчанию)строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...