Объединение с использованием XSLT v1.0 в преобразовании XML в XML - PullRequest
0 голосов
/ 04 февраля 2019

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

Входной файл

<?xml version="1.0"?>
<Root>
  <ParentNode>
    <Node>
      <Id>1</Id>
      <Date>2019-02-01</Date>
      <ReferenceLine>1</ReferenceLine>
    </Node>
    <Node>
      <Id>2</Id>
      <Date>2019-02-01</Date>
      <ReferenceLine>1</ReferenceLine>
    </Node>
    <Node>
      <Id>3</Id>
      <Date>2019-02-02</Date>
      <ReferenceLine>2</ReferenceLine>
    </Node>
  </ParentNode>
</Root>

Выходной файл

<Lines>
  <Line>
    <LineNum>1</LineNum>
    <Node>1 - 2</Node>
  </Line>
 <Line>
    <LineNum>2</LineNum>
    <Node>3</Node>
 </Line>
</Lines>

Итак, мне нужно объединить в выходных данных все узлы, которые появляются со ссылкой на строку.Хотя у меня может быть несколько вхождений узла во входном файле, в выходном файле у меня может быть только одно вхождение в узле линии.

1 Ответ

0 голосов
/ 04 февраля 2019

Вы можете добиться с помощью этого метода XSLT-1.0 Muenchian Grouping .Если вы ищете на SO, вы найдете много примеров.Применяя этот метод, ваша таблица стилей может выглядеть следующим образом.

Эта таблица стилей объединяет все Id, разделенные -.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:key name="nd" match="Node" use="ReferenceLine" />   

<xsl:template match="/Root/ParentNode">
    <Lines>
        <xsl:for-each select="Node[generate-id() = generate-id(key('nd',ReferenceLine)[1])]">
            <Line>
                <LineNum><xsl:value-of select="Id" /></LineNum>
                <Node>
                    <xsl:for-each select="key('nd',ReferenceLine)">
                        <xsl:sort order="ascending" select="Id" />
                        <xsl:value-of select="Id" />
                        <xsl:if test="position() != last()">
                            <xsl:text> - </xsl:text>
                        </xsl:if>
                    </xsl:for-each>
                </Node>
            </Line>
        </xsl:for-each>
    </Lines>
</xsl:template>

</xsl:stylesheet>

Если вы хотите получить только диапазон в результате, замените внутренний for-each со следующим:

...
<xsl:for-each select="key('nd',ReferenceLine)">
    <xsl:sort order="ascending" select="Id" />
    <xsl:if test="position() = 1">
        <xsl:value-of select="Id" />
    </xsl:if>
    <xsl:if test="position() = last() and position() != 1">
        <xsl:value-of select="concat(' - ',Id)" />
    </xsl:if>
</xsl:for-each>
...

Но имейте в виду, что этот диапазон будет игнорировать пробелы и использовать только самое низкое и самое высокое значение.

...