Как мне объединить или объединить сгруппированные узлы? - PullRequest
1 голос
/ 15 марта 2010

Использование XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output method="xml"/>
    <xsl:template match="/">
        <records>
            <record>
                <!-- Group record by bigID, for further processing -->
                <xsl:for-each-group select="records/record" group-by="bigID">
                    <xsl:sort select="bigID"/>
                    <xsl:for-each select="current-group()">
                        <!-- Create new combined record -->
                        <bigID>
                            <!-- <xsl:value-of select="."/> -->
                            <xsl:for-each select=".">
                                <xsl:value-of select="bigID"/>
                            </xsl:for-each>
                        </bigID>
                        <text>
                            <xsl:value-of select="text"/>
                        </text>
                    </xsl:for-each>
                </xsl:for-each-group>
            </record>
        </records>
    </xsl:template>
</xsl:stylesheet>

Я пытаюсь изменить:

<?xml version="1.0" encoding="UTF-8"?>
<records>
    <record>
        <bigID>123</bigID>
        <text>Contains text for 123</text>
        <bigID>456</bigID>
        <text>Some 456 text</text>
        <bigID>123</bigID>
        <text>More 123 text</text>
        <bigID>123</bigID>
        <text>Yet more 123 text</text>
    </record>
</records>

в

<?xml version="1.0" encoding="UTF-8"?>
<records>
    <record>
        <bigID>123
            <text>Contains text for 123</text>
            <text>More 123 text</text>
            <text>Yet more 123 text</text>
        </bigID>
        <bigID>456
            <text>Some 456 text</text>
        </bigID>
    </record>
</records>

Сейчас я просто перечисляю сгруппированные <bigID> индивидуально. Мне не хватает шага после группировки, где я объединяю сгруппированные узлы <bigID>. Я подозреваю, что мне нужно как-то использовать функцию «ключ», но я не уверен.

Спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 16 марта 2010

В XSLT 2.0 вам не нужны ключи для группировки.

Поскольку вы просто копируете элементы text в группе, можно удалить внутренний элемент for-each.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <records>
            <record>
                <xsl:for-each-group select="records/record/bigID" group-by=".">
                    <xsl:sort select="." data-type="number" />
                    <bigID>
                        <xsl:value-of select="." />
                        <xsl:copy-of select="current-group()/following-sibling::text[1]" />
                    </bigID>
                </xsl:for-each-group>
            </record>
        </records>
    </xsl:template>

</xsl:stylesheet>

Если вместо этого вы хотите вывести элементы bigID, за которыми следуют их текстовые элементы, мой цикл будет заменен следующим:

<xsl:for-each-group select="records/record/bigID" group-by=".">
    <xsl:sort select="." data-type="number" />
    <xsl:copy-of select="." />
    <xsl:copy-of select="current-group()/following-sibling::text[1]" />
</xsl:for-each-group>
0 голосов
/ 16 марта 2010

Вот нужное преобразование XSLT 2.0 :

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

    <xsl:key name="kTextforId" match="text"
         use="preceding-sibling::bigID[1]"/>

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

  <xsl:template match="record">
   <record>
    <xsl:for-each-group select="bigID" group-by=".">
     <bigID>
       <xsl:sequence select="current-grouping-key()"/>

       <xsl:copy-of select=
       "key('kTextforId', current-grouping-key())"/>
     </bigID>
    </xsl:for-each-group>
   </record>
  </xsl:template>
</xsl:stylesheet>

При выполнении с предоставленным XML-документом будет получен требуемый результат.

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