我需要通过按名称组合父/子/孙/等节点来从多层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>
答案 0 :(得分:1)
怎么样:
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>