Заказ дополнительных элементов с помощью XSLT - PullRequest
0 голосов
/ 17 октября 2018

У меня есть некоторый XML, представляющий различные элементы с тремя полями каждое (field1, field2, field3) и, возможно, два дополнительных поля (field4, field5), например:

<items>
    <data type="basic">
        <field1>A1</field1>
        <field2>A2</field2>
        <field3>A3</field3>
    </data>
    <data type="basic">
        <field1>B1</field1>
        <field2>B2</field2>
        <field3>B3</field3>
    </data>
    <data type="basic">
        <field1>C1</field1>
        <field2>C2</field2>
        <field3>C3</field3>
    </data>
    <data type="extra">
        <field4>C4</field4>
        <field5>C5</field5>
    </data>
    <data type="basic">
        <field1>D1</field1>
        <field2>D2</field2>
        <field3>D3</field3>
    </data>
    <data type="basic">
        <field1>E1</field1>
        <field2>E2</field2>
        <field3>E3</field3>
    </data>
    <data type="extra">
        <field4>E4</field4>
        <field5>E5</field5>
    </data>
</items>

Я хочу сгруппировать их вболее упорядоченным образом, как это:

<items>
    <item>
        <field1>A1</field1>
        <field2>A2</field2>
        <field3>A3</field3>
    </item>
    <item>
        <field1>B1</field1>
        <field2>B2</field2>
        <field3>B3</field3>
    </item>
    <item>
        <field1>C1</field1>
        <field2>C2</field2>
        <field3>C3</field3>
        <field4>C4</field4>
        <field5>C5</field5>
    </item>
    <item>
        <field1>D1</field1>
        <field2>D2</field2>
        <field3>D3</field3>
    </item>
    <item>
        <field1>E1</field1>
        <field2>E2</field2>
        <field3>E3</field3>
        <field4>E4</field4>
        <field5>E5</field5>
    </item>
</items>

Как я могу сделать это с XSLT?Я пробовал что-то вроде:

<items>
    <xsl:apply-templates select="data[type='basic']"/>
</items>

<xsl:template match="data[type='basic']">
    <item>
        ...
    </item>
</xsl:template>

Но я не знаю, как сопоставить соответствующие дополнительные поля с правильным элементом элемента.

1 Ответ

0 голосов
/ 17 октября 2018

Во-первых, обратите внимание, что type является атрибутом, поэтому вам нужно использовать префикс @ для обозначения этого

 <xsl:apply-templates select="data[@type='basic']"/>

Затем, в вашем шаблоне, совпадающем с базовыми элементами, вам сначала потребуетсявыберите дочерние узлы ...

<xsl:apply-templates />

Затем вам нужно выбрать первый следующий элемент data, но только если он является "дополнительным"

<xsl:apply-templates select="following-sibling::data[1][@type='extra']" />

.иметь шаблон, соответствующий «дополнительному» шаблону для вывода его узлов

<xsl:template match="data[@type='extra']">
  <xsl:apply-templates />
</xsl:template>

Попробуйте этот XSLT

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

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

  <xsl:template match="items">
    <items>
      <xsl:apply-templates select="data[@type='basic']"/>
    </items>
  </xsl:template>

  <xsl:template match="data[@type='basic']">
    <item>
      <xsl:apply-templates />
      <xsl:apply-templates select="following-sibling::data[1][@type='extra']" />
    </item>
  </xsl:template>

  <xsl:template match="data[@type='extra']">
    <xsl:apply-templates />
  </xsl:template>
</xsl:stylesheet>

Обратите внимание на использование шаблона идентификации для копирования всех других узлов.(Замените это на <xsl:mode on-no-match="shallow-copy"/>, если вы используете XSLT 3.0)

Также обратите внимание, что вы можете сделать <xsl:apply-templates select="following-sibling::data[1][@type='extra']/*" />.Тогда вам не понадобится шаблон для «лишнего».

Смотрите его в действии на http://xsltfiddle.liberty -development.net / nc4NzR9

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