使用 xslt 1.0 解析 CDATA 值



我想使用 xslt 转换一些 xml 文件,但遇到了一个大问题。

在我的输入文件中,我有 CDATA 标签,其中包含 xml 子树,应该复制到输出标签。我们知道有关这些 CDATA 标签的一些信息:

它们有一个特定的名称:SUBXML1、SUBXML2、SUBXML3等等。它们的内容是固定的:其中一些 SUBXMLn-s 只包含一个元素 (...),其中一些包含元素列表(......),或多个和/或元素列表(.........)。

我想使用 IBM Message Broker(xsl 转换节点,我们将其用于一百种类型的消息,但到目前为止还没有这个问题)来转换它们。我们对这些转换有严格的规则:我们不能使用其他任何东西,我们必须通过 XLS 实现目标;我们只能使用 XSLT 1.0(代理不支持 2.0 或 3.0);我们无法更改输入/输出消息的结构(许多系统使用定义的结构,因此我们无法触摸它们)。

所以事情是这样的:

我有一个输入 XML 文档:

<ns1:myOperation xmlns:ns1="http://mynamespace/">
    <SUBXML1>
        <![CDATA[<metaData><value>value1</value></metaData><metaData><value>value2</value></metaData><notMetaData><notValue>value3</notValue></notMetaData>]]>
    </SUBXML1>
</ns1:myOperation>

我有这样的xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://mynamespace/">
    <xsl:output method="xml" version="1.0" encoding="UTF-8"
        indent="yes" omit-xml-declaration="yes" />
    <xsl:template match="/">
        <xsl:apply-templates select="ns1:myOperation" />
    </xsl:template>
    <xsl:template match="ns1:myOperation">
        <ns1:myOperation>
            <xsl:apply-templates select="SUBXML1" />
        </ns1:myOperation>
    </xsl:template>
    <xsl:template match="SUBXML1">
        <xsl:element name="one">
            <xsl:element name="metaData">
                <xsl:value-of
                    select="substring-before(substring-after(.,'metaData&gt;'), '&lt;/metaData')" disable-output-escaping="yes" />
            </xsl:element>
        </xsl:element>
        <xsl:element name="all">
            <xsl:element name="allSUBXML1">
                <xsl:value-of
                    select="." disable-output-escaping="yes" />
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

其输出将是:

<ns1:myOperation xmlns:ns1="http://mynamespace/">
    <one>
        <metaData>
            <value>value1</value>
        </metaData>
    </one>
    <all>
        <allSUBXML1 />
    </all>
</ns1:myOperation>

注意:如果你在 eclipse 中测试这个例子,它将起作用(不会为空),但是 xsl:value-of select 应该只在元素中工作!因此,在消息代理中,它将生成一个 emtpy 元素,但在 eclipse 中(也许是一个错误?),它将生成一个"完整输出",因此,它将用SUBXML1内容填充该字段。

回到我的问题:转换后的 xml 在 节点中没有任何内容,因为我在 下没有元素(只有一个大文本)...... 在我的输入 xml 中。

如何实现我的目标(将SUBXML1中的所有内容复制到输出的所需元素)?

我不能使用选择的值,因为SUBXML1下没有元素,只有一个大字符串。我不能使用 copy-of,因为如果不能正确转换 CDATA(我不想在我的输出中看到"&lt;"和"&gt;",它应该是一个有效的 XML 子树)。

正如你所看到的,我试图用substring-before(substrin-after(.,...), ...)做一些技巧,从SUBXML1那里得到一个内部元素,它有效,但这还不够。

有没有任何棘手的方法可以将所有内容从复制到(所以所有内部元素)?

谢谢转发,塔马斯

你对使用 XSLT 已经死心塌地了吗?我认为,您可以使用 ESQL 中的解析为比特流子句来轻松做到这一点。

最新更新