XSLT将简单标记带入XML中的复杂标记之上

时间:2016-11-21 08:11:58

标签: xml xslt

我有一个XML,在嵌套标签之后会出现很少的简单标签。如果可以将所有简单标签带到嵌套标签之上,我试图找到一种方法。 示例

<Country>
<row>
    <CountryId>1</CountryId>
    <State>
        <StateId>2</StateId>
        <StateName>Karnataka</StateName>
    </State>
    <CountryName>India</CountryName>
</row>
<row>
    <CountryId>3</CountryId>
    <State>
        <StateId>4</StateId>
        <StateName>Sydney</StateName>
    </State>
    <CountryName>Australia</CountryName>
</row>

预期的转换XML是:

<Country>
<row>
    <CountryId>1</CountryId>
    <CountryName>India</CountryName>
    <State>
        <StateId>2</StateId>
        <StateName>Karnataka</StateName>
    </State>
</row>
<row>
    <CountryId>3</CountryId>
    <CountryName>Australia</CountryName>
    <State>
        <StateId>4</StateId>
        <StateName>Sydney</StateName>
    </State>
</row>

这个XML可以是任何具有n级的通用XML,因此我想对XSLT中的任何标记进行硬编码。 XSLT应该能够处理一个巨大的XML,将所有简单标记带到嵌套标记之上。是否建议使用XSLT执行此操作?还有哪些其他选择?

2 个答案:

答案 0 :(得分:2)

如果您没有混合内容(即具有文本和元素内容的元素),您只需为具有元素内容match="*[*]"的元素编写模板,该元素在子元素之前首先处理子元素而不包含子元素元素与子元素。使用可以通过

实现的XSLT 2.0
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="yes"/>

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

    <xsl:template match="*[*]">
        <xsl:copy>
            <xsl:apply-templates select="@*, *[not(*)], *[*]"/>
        </xsl:copy>
    </xsl:template>

</xsl:transform>

在线http://xsltransform.net/pPJ8LVo

如果您只有XSLT 1.0处理器,那么您必须将<xsl:apply-templates select="@*, *[not(*)], *[*]"/>分解为

<xsl:apply-templates select="@* | *[not(*)]"/>
<xsl:apply-templates select="*[*]"/>

答案 1 :(得分:2)

我会这样做:

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="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()">
            <xsl:sort select="boolean(*)" data-type="text" order="ascending"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>