XSLT: невозможно применить преобразование после создания вложенного узла - PullRequest
0 голосов
/ 26 мая 2020

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

https://xsltfiddle.liberty-development.net/93dFeq9

)

Ввод XML:

<root>
    <person>
        <a/>
        <b/>
        <c/>
        <d/>
    </person>

    <person>
        <a/>
        <b/>
        <c/>
        <d/>
    </person>
</root>

XSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"  xmlns:mf="http://example.com/mf">
    <xsl:output method="xml" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />


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

    <xsl:template match="(a | b |c |d)">
        <xsl:element name="{name()}">
            <xsl:attribute name="type">alpha</xsl:attribute>
        </xsl:element>
    </xsl:template>


    <xsl:function name="mf:nest" as="node()*">
        <xsl:param name="nodesl" as="node()*"/>
        <xsl:for-each-group select="$nodesl" group-adjacent="true()">
            <xsl:copy select=".">
                <xsl:sequence select="mf:nest(tail(current-group()))"/>    
            </xsl:copy>

        </xsl:for-each-group>
    </xsl:function>

    <xsl:template match="person">
        <xsl:copy>
            <xsl:sequence select="mf:nest(*)"/>
        </xsl:copy>
    </xsl:template>

</xsl:transform>

Фактический выход XML:

<root>
    <person>
      <a>
         <b>
            <c>
               <d/>
            </c>
         </b>
      </a>
   </person>

    <person>
      <a>
         <b>
            <c>
               <d/>
            </c>
         </b>
      </a>
   </person>
</root>

Ожидаемый результат XML:

<root>
    <person>
      <a type="alpha">
         <b type="alpha">
            <c type="alpha">
               <d type="alpha"/>
            </c>
         </b>
      </a>
   </person>

    <person>
      <a type="alpha">
         <b type="alpha">
            <c type="alpha">
               <d type="alpha"/>
            </c>
         </b>
      </a>
   </person>
</root>

1 Ответ

0 голосов
/ 26 мая 2020

Я думаю, вам нужно применить шаблоны к результату функции и в шаблоне, добавив атрибут:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"  xmlns:mf="http://example.com/mf">
    <xsl:output method="xml" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />


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

    <xsl:template match="a | b |c |d">
        <xsl:element name="{name()}">
            <xsl:attribute name="type">alpha</xsl:attribute>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>


    <xsl:function name="mf:nest" as="node()*">
        <xsl:param name="nodesl" as="node()*"/>
        <xsl:for-each-group select="$nodesl" group-adjacent="true()">
            <xsl:copy>
                <xsl:sequence select="mf:nest(tail(current-group()))"/>    
            </xsl:copy>

        </xsl:for-each-group>
    </xsl:function>

    <xsl:template match="person">
        <xsl:copy>
            <xsl:apply-templates select="mf:nest(*)"/>
        </xsl:copy>
    </xsl:template>

</xsl:transform>

https://xsltfiddle.liberty-development.net/93dFeq9/1

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

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="a | b |c |d" mode="nest">
    <xsl:element name="{name()}">
        <xsl:attribute name="type">alpha</xsl:attribute>
        <xsl:apply-templates select="following-sibling::*[1]" mode="nest"/>
    </xsl:element>
</xsl:template>

<xsl:template match="person">
    <xsl:copy>
        <xsl:apply-templates select="*[1]" mode="nest"/>
    </xsl:copy>
</xsl:template>

выполняет свою работу: https://xsltfiddle.liberty-development.net/93dFeq9/2

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