XSLT 1.0 - переместить определенные элементы в нового родителя - PullRequest
0 голосов
/ 17 января 2019

Спасибо, что нашли время посмотреть на мой вопрос

У меня есть исходный XML, который выглядит так

   <root>
    <a>asdf</a>
    <b>asdfdsaf</b>
    <c>adfasd</c>
    <d>asddf</d>
    <e></e>
    <others>
        <foo>sdfd</foo>
        <bar>hghg</bar>
    </others>
</root>

Мне нужно обернуть некоторые элементы, например, a, b, c, в нового родителя и удалить пустые элементы.

так выводить вот так

   <root>
    <newparent>
        <a>asdf</a>
        <b>asdfdsaf</b>
        <c>adfasd</c>
    </newparent>
    <d>asddf</d>
    <others>
        <foo>sdfd</foo>
        <bar>hghg</bar>
    </others>
</root>

Мне удалось удалить пустые элементы, используя этот XSL -

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(@*) and not(*) and (not(text()) or .=-1)]"/>

    <xsl:template match="name">


    </xsl:template>

</xsl:stylesheet>

Застревание при добавлении нового родительского узла. Любые указатели / помощь очень ценится.

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Попробуйте так:

XSLT 1.0

<xsl:stylesheet version="1.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="*"/>

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

<xsl:template match="/root">
    <xsl:copy>
        <newparent>
            <xsl:apply-templates select="a|b|c"/>
        </newparent>
        <xsl:apply-templates select="*[not(self::a or self::b or self::c)]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[not(@* or node())]"/>

</xsl:stylesheet>
0 голосов
/ 17 января 2019
<xsl:template match="root">
        <xsl:copy>
            <newparent>
                <xsl:copy-of select="a|b|c"/>
             </newparent>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[.= '' or name() ='a' or name()='b' or name()='c']"/>
check it if it is fullfill your requirement.
...