如何使用XSLT将所有父/子/孙子节点展平为单层XML

u1

我需要通过按名称组合parent / children / grandchildren / etc ...节点来从多层xml中创建单层xml文档。

例:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header/>
    <S:Body>
        <theparents>
            <parent1>
                <child1>
                    <grandchild1>value1</grandchild1>
                </child1>
                <child2>value2</child2>
            </parent1>

            <parent2>
                <child1>value3</child1>
                <child2>
                    <grandchild2>value4</grandchild2>
                </child2>
            </parent2>
        </theparents>
    </S:Body>
</S:Envelope>

转换为

 <parent1_child1_grandchild1>value<parent1_child1_grandchild1>
    <parent1_child2>value</parent1_child2>
    <parent2_child1>value</parent2_child1>
    <parent2_child2_grandchild2>value</parent2_child2_grandchild2>

我能够在单个子节点级别上执行此操作,但是当它深达几层时会遇到困难

XSLT:

 <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:flatten="http://www.example.org/FLATTEN/">
        <xsl:output method="xml" indent="yes"/>

        <xsl:template match="/">
            <Result2>
                <xsl:apply-templates select="/S:Envelope/S:Body/*[local-name()='theparents']/*"/>
            </Result2>
        </xsl:template>

        <xsl:template match="*[local-name()='theparents']/*">
            <xsl:apply-templates select="*">
                <xsl:with-param name="prefix" select="name()"/>
            </xsl:apply-templates>
        </xsl:template>

        <xsl:template match="*">
            <xsl:param name="prefix"/>
            <xsl:choose>
                <xsl:when test="$prefix">
                    <xsl:variable name="elementName" select="local-name()"/>
                    <xsl:element name="{$prefix}_{$elementName}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:message terminate="no">WARNING: Unmatched element: <xsl:value-of select="name()"/>
                    </xsl:message>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>

    </xsl:stylesheet>

XML输入样例:

  <?xml version='1.0' encoding='UTF-8'?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Header/>
        <S:Body>
            <theparents>
                <parent1>
                    <child1>
                        <grandchild1>value</grandchild1>
                    </child1>
                    <child2>value</child2>
                </parent1>

                <parent2>
                    <child1>value</child1>
                    <child2>
                        <grandchild2>value</grandchild2>
                    </child2>
                </parent2>
            </theparents>
        </S:Body>
    </S:Envelope>

当前结果:

 <Result2 xmlns:fo="http://www.w3.org/1999/XSL/Format"
        xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:flatten="http://www.example.org/FLATTEN/">
        <parent1_child1>
            value
        </parent1_child1>
        <parent1_child2>value</parent1_child2>
        <parent2_child1>value</parent2_child1>
        <parent2_child2>
            value
        </parent2_child2>
    </Result2>

所需结果:

<Result2 xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:flatten="http://www.example.org/FLATTEN/">
    <parent1_child1_grandchild1>value1</parent1_child1_grandchild1>
    <parent1_child2>value2</parent1_child2>
    <parent2_child1>value3</parent2_child1>
    <parent2_child2_grandchild2>value4</parent2_child2_grandchild2>
</Result2>
michael.hor257k

怎么样:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
exclude-result-prefixes="S">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <Result2>
        <xsl:apply-templates select="S:Envelope/S:Body/theparents/*"/>
    </Result2>
</xsl:template>

<xsl:template match="*[*]">
    <xsl:param name="ancestor-names"/>
    <xsl:apply-templates select="*">
        <xsl:with-param name="ancestor-names" select="concat($ancestor-names,  name(), '-')"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="*">
    <xsl:param name="ancestor-names"/>
    <xsl:element name="{concat($ancestor-names, name())}">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章