Заполните атрибут и значения для всех родительских узлов XML-файла из 4-го родительского узла


Я новичок в XSLT и хотел бы добавить атрибут и значение одного и того же для всех родительских узлов, начиная со 2-го родительского узла. здесь логика должна быть такой: если есть главный узел, атрибут (Mainattribute) должен быть один раз, а для остальных всех родительских узлов под главным узлом должен быть другой атрибут(childattribute), который должен быть одинаковым во всех других узлах, кроме главного.

У нас есть входной xml, как показано ниже : это просто есть только некоторые поля, в идеале будет больше тегов и может отличаться.

            <?xml version="1.0" encoding="UTF-8"?>
            <Header>
                <Main>
                    <Parent2>
                        <status>12</status>
                        <statusmsg>Helo</status_text>
                    </Parent2>
                    <Parent3>
                        <Child1>112</Child1>
                        <Child2>Hai</Child2>
                    </Parent3>
                    <Parent4>
                        <Child3>Valley</Child3>
                        <Parent5>
                            <Child7>Kind</Child1>
                            <Child8>Pls</Child2>
                        </Parent5>
                    </Parent4>
                </Main>
            </Header>

Выходные данные должны быть такими, как показано ниже:

        <?xml version="1.0" encoding="UTF-8"?>
        <Header>
            <Main Mainattribute="1">
                <Parent2 childattribute="1">
                    <status>12</status>
                    <statusmsg>Helo</status_text>
                </Parent2>
                <Parent3 childattribute="1">
                    <Child1>112</Child1>
                    <Child2>Hai</Child2>
                </Parent3>
                <Parent4 childattribute="1">
                    <Child3>Valley</Child3>
                    <Parent5 childattribute="1">
                        <Child7>Kind</Child1>
                        <Child8>Pls</Child2>
                    </Parent5>
                </Parent4>
            </Main>
        </Header>

Может ли кто-нибудь поделиться XSLT для того же самого. я пробовал так много случаев, но не смог достичь этого. Спасибо

Ниже XSLT пытался для первого основного узла, но почему-то получил ошибку и не смог продолжить дальше.

        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:output indent="yes"/>
            <!-- Template to copy all the elements -->
            <xsl:template match="@*|node()">
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:template>

            <xsl:template match="Main">
                <Main>
                    <xsl:attribute name="Mainattribute">
                        <xsl:value-of select="1"/>
                    </xsl:attribute>
                    <xsl:apply-templates select="child::node()"/>
                </Main>
            </xsl:template>



        </xsl:stylesheet>
2 2

2 ответа:

Улучшая ответ @Aniket V, вы можете использовать режимы вместо того, чтобы зависеть от имени тега:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="Main">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="Mainattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates mode="parent_mode"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*" mode="parent_mode">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="childattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Обновить

Если вы хотите обновить все XML-элементы, которые имеют дочерние элементы (но не элемент верхнего уровня), то это преобразование является вашим:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="Main" priority="1">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="Mainattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[child::* and ancestor::*]">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:attribute name="childattribute"><xsl:value-of select="1"/></xsl:attribute>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Вы довольно близки с изменениями XSLT. Пожалуйста, измените шаблоны, как показано ниже.

Шаблон для <Main>

<xsl:template match="Main">
    <xsl:copy>
        <xsl:attribute name="Mainattribute">
            <xsl:value-of select="1" />
        </xsl:attribute>
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

Шаблон для узлов, имеющих имя Parent.

<xsl:template match="*[contains(name(), 'Parent')]">
    <xsl:copy>
        <xsl:attribute name="childattribute">
            <xsl:value-of select="1" />
        </xsl:attribute>
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>