使用xslt 1.0解析CDATA值

时间:2015-02-02 11:04:05

标签: xslt xslt-1.0 messagebroker

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

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

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

我想使用IBM Message Broker转换它们(xsl转换节点,我们将它用于100种类型的消息,但到目前为止还没有这个问题)。我们对这些转换有严格的规则:我们不能使用其他任何东西,我们必须用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中测试此示例,它将起作用(&lt; allSUBXML1&gt;不会为空),但是xsl:value-of select应仅适用于元素!因此,在消息代理中,它将生成一个emtpy&lt; allSUBXML1 /&gt;元素,但在某种程度上的日食(可能是一个错误?)它会生成一个&#34;完整的输出&#34;因此,它会使用SUBXML1内容填充该字段。

回到我的问题:转化的xml在&lt; allSUBXML1 /&gt;中没有任何内容。节点,因为我在&lt; SUBXML1&gt; ...&lt; / SUBXML1&gt;下没有元素(只有大文本)在我的输入xml。

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

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

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

是否有任何棘手的方法可以复制来自&lt; SUBXML1&gt;的所有内容到&lt; allSUBXML1&gt; (所以所有的内在元素)?

谢谢你, 的Tamas

1 个答案:

答案 0 :(得分:0)

您是否已经开始使用XSLT?您可以使用ESQL中的parse作为比特流子句来实现这一点,我认为这很容易。