Получение всех следующих братьев и сестер до определенного атрибута - PullRequest
0 голосов
/ 20 февраля 2019

Из следующего XML

<Rows>
    <Row RowNo="1" ProductNo="Product1" ProductText="Some Other Text" Type="A"/>
    <Row RowNo="2" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="3" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="4" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="5" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="6" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="7" ProductNo="Product2" ProductText="Some Other Text" Type="A"/>
    <Row RowNo="8" ProductNo="Product3" ProductText="Some Other Text" Type="A"/>
    <Row RowNo="9" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="10" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="11" ProductNo="Product4" ProductText="Some Other Text" Type="A"/>
    <Row RowNo="12" ProductNo="" ProductText="Some Text" Type="T"/>
    <Row RowNo="13" ProductNo="" ProductText="Some Text" Type="T"/>
</Rows>

Я хочу преобразовать в следующее:

<Line>
    <ID>1</ID>
    <Note>Some Text\nSome Text\nSome Text\nSome Text\nSome Text</Note>
    <Description>Product 1</Description>
</Line>
<Line>
    <ID>2</ID>
    <Description>Product 2</Description>
</Line>
<Line>
    <ID>3</ID>
    <Note>Some Text\nSome Text</Note>
    <Description>Product 3</Description>
</Line>
<Line>
    <ID>4</ID>
    <Note>Some Text\nSome Text</Note>
    <Description>Product 4</Description>
</Line>

У меня завершено создание строки, это «Примечание», с которым у меня проблемы.Для каждой строки Type = 'T' я хочу взять значение атрибута ProductText и объединить их с новой строкой.Если нижестоящий элемент является «A-line», узел Note не должен создаваться.Я попытался использовать

<xsl:template match="/Rows/Row[@Type!='T']">
    <xsl:element name="Line">
        <xsl:element name="ID">
            <xsl:value-of select="@RowNo"/>
        </xsl:element>
        <xsl:element name="cbc:Note">
            <xsl:value-of select="following-sibling::*[@Type='T']/@ProductText"/>
        </xsl:element>
        <xsl:element name="Description">
            <xsl:value-of select="@ProductNo"/>
        </xsl:element>
    </xsl:element>
</xsl:template>

, но это (конечно) помещает все 'T-линии' в узел Note в каждой строке.

Я использую XSLT 2.0

Любая помощь будет оценена

1 Ответ

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

В XSLT 2.0 это относительно простая группировка проблема:

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

<xsl:template match="/Rows">
    <Lines>
        <xsl:for-each-group select="Row" group-starting-with="Row[@Type='A']">
            <Line>
                <ID>
                    <xsl:value-of select="position()"/>
                </ID>
                <xsl:if test="current-group()[@Type='T']">
                    <Note>
                        <xsl:value-of select="current-group()[@Type='T']/@ProductText" separator="\n"/>
                    </Note>
                </xsl:if>
                <Description>
                    <xsl:value-of select="@ProductNo"/>
                </Description>
            </Line>
        </xsl:for-each-group>
    </Lines>
</xsl:template>

</xsl:stylesheet>

Обратите внимание на добавленный корневой элемент Lines.Без этого результат не будет правильно сформированным документом XML.


PS В XML \n - это бессмысленная строка, а не символ перевода строки.

...