xslt如何读取文档节点()

时间:2014-10-23 06:34:18

标签: xslt-2.0

我有一个xml文件,其中一个元素有CDATA作为值。我将CDATA值放入一个变量中,当我从oXygen调试代码时,我可以看到它是document-node(1)的值类型。如何迭代document-node()

copy可以给我一个新的xml文件。但我需要的不是一个新文件。我只需要读取某些节点并根据这些节点上的值生成报告。所以我直接将CDATA复制到我的变量,并认为我可以操纵它。

  1. 我尝试使用substring来读取变量,但失败了。
  2. 我尝试使用document(variable)打开变量,但Oxygen给出了FODC0002:I/O error reported by xml parser processing file.的调试错误 这里的文件是我的变量,看起来像一个xml文件
  3. 我在google上搜索了错误,但是在使用document()时只得到了Oxygen throw I / O错误这样的非封闭式问题。

    有人会让我知道出了什么问题吗?还是给我一个更好的解决方案?

    我也尝试过parse-xml()但是我从Saxon那里得到了以下错误:

    F[Saxon-EE9.5.1.5] the processing instruction target matching "[xX][mM][lL]" is not allowed
    F[Saxon-EE9.5.1.5] FODC0006: First argument to parse-xml() is not a well formed and namespace-well-formed XML document.
    

    我使用parse-xml的代码如下:

    <xsl:template match="data"
     <xsl:for-each select="parse-xml(root/outsideData)//nodeLevel1/nodeLevel2">
    

    有人可以给我一个关于如何使用parse-xml()的示例吗?我做谷歌搜索,但没有找到有用的样本。

    非常感谢!

    我的数据如下:

    <root>
        <outsideData id="123">
            <child1 key="124375438"/>
            <![CDATA[ <?xml version=1.0 encoding="UTF-8"?><insideData  xmlns:xlink="http://www.w3.org/1999/xlink">
                <nodeLevel1>
                    <nodeLevel21>packing</nodeLevel21>
                    <nodeLevel22 ref="12343-454/560" xlink:href="URN:X-MN:DD%3FM=B888%26SDC=A%26CH=79% .../>
                </nodeLevel1>
           ]]>
        </outsideData>
    </root>
    

    我想获得内部CDATA <nodeLevel22> @ref and @xlink,这将获得DD-FM-B888-26-79

    我的变数是:

    <xsl:for-each select="/root/outsideData">
                    <xsl:variable name="insideData">
                        <xsl:value-of select="." disable-output-escaping="yes"/>
                    </xsl:variable>
                    <xsl:variable name="Data">
                        <xsl:value-of
                            select="normalize-space(substring-after($insideData,'?&gt;'))"
                            disable-output-escaping="yes"/>
                    </xsl:variable>
    </xsl:foreach>
    

    从调试中我可以看到变量insideDataData都是值类型document-node(1)

    Martin的解决方案非常适合我:)

    但我仍然想知道为什么以下不起作用:

    <xsl:variable name="insideData">
        <xsl:value-of select="." disable-output-escaping="yes"/>
    </xsl:variable>
    <ref>
        <xsl:value-of select="substring-before(substring-after($insideData, '&lt;nodeLevel22 ref'),&gt;/>')"/>
    </ref>
    

    我在这里空<ref/>

1 个答案:

答案 0 :(得分:0)

如果您执行<xsl:variable name="varName"><xsl:value-of select="..."/><xsl:variable>,那么您正在创建一个临时文档片段,其中包含一个文本,其中包含value-of中所选项目的字符串内容。在大多数情况下这没有意义,做<xsl:variable name="varName" select="..."/>通常就足够了。

至于使用outsideData解析parse-xml元素的内容,确实不仅在该元素中有转义的XML文档而且还有空格,因此如果您尝试将内容解析为XML不允许在XML声明之前将该错误作为空格。将XML填充到带有混合内容的元素的CDATA部分的整个方法在我看来是有缺陷的,如果你想将转义的XML存储到CDATA中,那么你应该确保使用只包含CDATA的单个元素然后只包含没有前导空格的XML标记的部分。

如果您无法更改输入数据的创建,那么您需要确保仅将元素的字符串内容的那部分传递给格式良好的XML文档parse-xml,所以你需要一些方法来在XML声明之前剥离空格,例如

<xsl:for-each select="/root/outsideData">
  <xsl:variable name="xml-string" select="replace(., '^\s+', '')"/>
  <xsl:variable name="xml-doc" select="parse-xml($xml-string)"/>
  <!-- now output data e.g. -->
  <xsl:value-of select="$xml-doc//nodeLevel1/nodeLevel22/@ref"/>
  ...
</xsl:for-each>

未经测试,但在尝试使用parse-xml时应该显示正确的方向。