XSLT Apply Templates для получения определенных записей родителя и потомка, потомки тоже могут быть родителями - PullRequest
0 голосов
/ 12 ноября 2018

Мне нужна помощь с моим XSLT.Вот моя структура XML.

<root>
<row>
    <component>mainfield_1</component>
    <type>Field</type>
    <where_used>
        <component>subfield_2</component>
        <type>Field</type>
    </where_used>
    <where_used>
        <component>report_1</component>
        <type>Report</type>
    </where_used>
</row>
<row>
    <component>subfield_2</component>
    <type>Field</type>
    <where_used>
        <component>report_2</component>
        <type>report</type>
    </where_used>
</row>
<row>
    <component>mainfield_3</component>
    <type>Field</type>
</row>
</root>

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

<root>
<row>
    <component>mainfield_1</component>
    <type>Field</type>
</row>
<row>
    <component>subfield_2</component>
    <type>Field</type>
</row>
<row>
    <component>report_1</component>
    <type>Report</type>
</row>
<row>
    <component>report_2</component>
    <type>report</type>
</row>
</root>

По сути, я пытаюсь получить все различные зависимости компонента mainfield_1.Вот мой пример кода, но этого недостаточно, чтобы найти любого подходящего родителя с тем же именем компонента, что и у дочерних элементов.

<xsl:template match="root">
    <root>
        <xsl:apply-templates select="row[component='mainfield_1']"/>
    </root>
</xsl:template>

<xsl:template match="row">
    <row>
        <component>
            <xsl:value-of select="component"/>
        </component>
        <type>
            <xsl:value-of select="type" />
        </type>
    </row>
    <xsl:apply-templates select="where_used"/>
</xsl:template>

<xsl:template match="where_used">
    <row>
        <component>
            <xsl:value-of select="component"/>
        </component>
        <type>
            <xsl:value-of select="type" />
        </type>
    </row>
</xsl:template>

Если я запусту вышеизложенное, я не смогу получить это.

<row>
  <component>report_2</component>
  <type>report</type>
</row>

Пожалуйста, помогите.

1 Ответ

0 голосов
/ 12 ноября 2018

Попробуйте использовать ключ для поиска row пунктов по component

<xsl:key name="rows" match="row" use="component" />

Тогда вы можете иметь шаблон для where_used узлов, которые ссылаются на отдельную строку, позволяя вам выбрать эту строку вместо

<xsl:template match="where_used[key('rows', component)]">
    <xsl:apply-templates select="key('rows', component)" />
</xsl:template>

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

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

    <xsl:key name="rows" match="row" use="component" />

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

    <xsl:template match="root">
        <root>
            <xsl:apply-templates select="row[component='mainfield_1']"/>
        </root>
    </xsl:template>

    <xsl:template match="row">
        <row>
            <xsl:apply-templates select="* except where_used" />
        </row>
        <xsl:apply-templates select="where_used"/>
    </xsl:template>

    <xsl:template match="where_used">
        <row>
            <xsl:apply-templates />
        </row>
    </xsl:template>    

    <xsl:template match="where_used[key('rows', component)]">
        <xsl:apply-templates select="key('rows', component)" />
    </xsl:template>
</xsl:stylesheet>

Примечание. Я также использовал шаблон идентификации, чтобы избежать явного копирования существующих узлов, которые не нужно изменять.

...