XSLT:如何将字符串转换为多个元素?

时间:2013-02-19 23:08:09

标签: xml xslt transformation

我试图转换这个XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<data>
    <entry>
        <databit>30.11.2012</databit>
        <databit>Foo</databit>
        <databit>Key: Value<br />Key: Value<br /> ... Key: Value</databit>
        <databit>some Foo content</databit>
        <databit>more Foo content</databit>
    </entry>
    <entry>
        ...
    </entry>
    ...
</data>

键值对的数量是可变的。分隔符始终为<br />标记。

输出应如下所示:

<data>
    <entry>
        <date>30.11.2012</date>
        <title>Foo</title>
        <info>
            <part key="Key" value="Value" />
            <part key="Key" value="Value" />
            <part key="Key" value="Value" />
        </info>
        <databit>some Foo content</databit>
        <databit>more Foo content</databit>
    </entry>
    <entry>
        ...
    </entry>
    ...
</data>

以下是我撰写的XSLT文档:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">
        <data>
            <xsl:for-each select="/data/entry">
                <entry>
                    <date>
                        <xsl:value-of select="databit[1]"/>
                    </date>
                    <title>
                        <xsl:value-of select="databit[2]"/>
                    </title>
                    <info>
                        <xsl:value-of select="databit[3]"/>
                    </info>
                    <category>
                        <xsl:value-of select="databit[4]"/>
                    </category>
                    <status>
                        <xsl:value-of select="databit[5]"/>
                    </status>
                </entry>
            </xsl:for-each>
        </data>
    </xsl:template>
</xsl:stylesheet>

但我不知道如何改造info

1 个答案:

答案 0 :(得分:2)

此样式表应创建所需的转换。样式表假定键和值始终用:分隔,并且它会删除冒号和空格字符,但不会删除其他字符。如果需要删除空格,请使用normalize-space()

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

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

    <xsl:template match="databit[1]">
        <date>
            <xsl:apply-templates/>
        </date>
    </xsl:template>

    <xsl:template match="databit[2]">
        <title>
            <xsl:apply-templates/>
        </title>
    </xsl:template>

    <xsl:template match="databit[3]">
        <info>
            <xsl:apply-templates/>
        </info>
    </xsl:template>

    <xsl:template match="databit[3]/text()">
        <part key="{substring-before(., ':')}" value="{substring(substring-after(., ':'), 2)}"/>
    </xsl:template>

    <xsl:template match="databit[3]/br"/>

</xsl:stylesheet>

样式表上的一些要点

  • 使用身份模板递归复制所有元素,除非该元素具有自己的模板
  • 第3个<databit>元素中的所有文本节点都应为键值对。
  • 使用大括号内的XPath表达式(属性值模板)添加<part>元素中的属性。添加它们的其他方法是使用<xsl:attribute>元素。
  • 使用空模板禁止复制元素<br>