当前位置: 首页 > 知识库问答 >
问题:

XSL:转义CDATA并在内部用for-each解析为xml

钱志
2023-03-14

我有一个xml文档(输入文件不能更改),我需要用xsl转换到另一个xml。输入xsl有一个CDATA,如以下示例结构所示:

<TestCaseElement>
    <Role>VP</Role>
    <Code>
        <Line>
            <![CDATA[<id>l1_SomeId1</id> <val1>l1_SomeVal1</val1> <val2>l1_SomeVal2</val2> <algo>l1_somealgo</algo>]]>
        </Line>
        <Line>
            <![CDATA[<id>l2_someid1</id> <val1>l2_SomeVal1<val1> <val2>l2_SomeVal2<val2> <algo>l2_somealgo</algo>]]>
        </Line>
    </Code>
<TestCaseElement>

预期结果如下:

<Expected>
    <MEASV id="l1_SomeId1" val1="l1_SomeVal1" val2="l1_SomeVal2" algo="l1_somealgo">
    <MEASV id="l2_SomeId1" val1="l2_SomeVal1" val2="l2_SomeVal2" algo="l2_somealgo">
</Expected>

我的Xslt看起来像:

<Expected>
    <xsl:for-each select="TestCaseElement[(Role='VP')]/Code/Line">                      
        <xsl:for-each select="current()/*">
            <MEASV>
                <xsl:attribute name="{fn:local-name()}"><xsl:value-of select="current()"/></xsl:attribute>
            </MEASV>
        </xsl:for-each>                                     
    </xsl:for-each>
</Expected>

问题是xslt无法识别CDATA中的标记。如何为每个应用某种禁用输出转义?或者其他方法来解决这个问题?

共有1个答案

盖向荣
2023-03-14

考虑使用XSLT 3(由Saxon 9.8和AltoVA XMLSPIPS/RAPTROR支持)和<代码> PARSE-XML-片段()/代码>:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <Expected>
            <xsl:apply-templates select="TestCaseElement[(Role = 'VP')]/Code/Line"/>
        </Expected>
    </xsl:template>

    <xsl:template match="Line">
        <MEASV>
            <xsl:apply-templates select="parse-xml-fragment(.)/*"/>
        </MEASV>
    </xsl:template>

    <xsl:template match="*">
        <xsl:attribute name="{local-name()}" select="."/>
    </xsl:template>

</xsl:stylesheet>

请注意,在您发布的示例中,有一个转义标记

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:err="http://www.w3.org/2005/xqt-errors"
    exclude-result-prefixes="xs math err"
    version="3.0">

    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <Expected>
            <xsl:apply-templates select="TestCaseElement[(Role = 'VP')]/Code/Line"/>
        </Expected>
    </xsl:template>

    <xsl:template match="Line">
        <MEASV>
            <xsl:try>
                <xsl:apply-templates select="parse-xml-fragment(.)/*"/>
                <xsl:catch errors="err:FODC0006">
                    <xsl:message select="'Error parsing', ."/>
                </xsl:catch>
            </xsl:try>
        </MEASV>
    </xsl:template>

    <xsl:template match="*">
        <xsl:attribute name="{local-name()}" select="."/>
    </xsl:template>

</xsl:stylesheet>

 类似资料:
  • 使用最熟悉的方法进行迭代 在这一期的 实战 Groovy 中,Scott Davis 提出了一组非常好的遍历方法,这些方法可以遍历数组、列表、文件、URL 以及很多其它内容。最令人印象深刻的是,Groovy 提供了一种一致的机制来遍历所有这些集合和其它内容。 迭代是编程的基础。您经常会遇到需要进行逐项遍历的内容,比如 List、File 和 JDBC ResultSet。Java 语言几乎总是提供

  • 我得到xml格式的响应,数据在xml节点的cData部分内。现在当我试图提取节点值,然后用cdata文本获取值。 我如何解析它? xml: 我使用代码来获取整个列表,但我只需要获取特定的节点 上面的代码列出了所有的cdata值... 我只需要从上面的xml中获取dbid、isdb、mydb值

  • 我想使用xslt转换一些xml文件,但遇到了一个大问题。 在我的输入文件中,我有CDATA标记,它包含xml子树-S,应该复制到输出标记中。我们知道关于这些CDATA标记的一些信息: 我的xsl如下所示: 这样做的输出将是: 注意:如果您在eclipse中测试这个示例,它可以工作( 不会为空),但是xsl:value-of select应该只在元素中工作!因此,在message broker中,它

  • 问题内容: 我在进行函数调用时试图找到for-each循环的工作方式。请参阅以下代码, 在版本1中,我在for- each循环中调用returnArr()方法,在版本2中,我显式调用returnArr()方法并将其分配给数组,然后对其进行迭代。两种方案的结果都相同。我想知道哪个更有效以及为什么。 我认为版本2会更高效,因为我不会在每次迭代中都调用method。但是令我惊讶的是,当我使用版本1调试代

  • 假设我有一个XML文件,如: 我想读取xslt转换器中的CDATA元素“name”,并将其值放在标记值的某个位置。我该怎么做?抱歉,我们不能对CDATA的内容使用xpath。是否有一些破解/解决方法?我希望在XSLT中严格执行此操作。

  • 本文向大家介绍Java for each实现机制代码原理解析,包括了Java for each实现机制代码原理解析的使用技巧和注意事项,需要的朋友参考一下 源测试代码如下 执行编译命令 javac ForEachTest.java 使用idea查看反编的Java文件 执行指令查看对应的汇编指令 javap -c ForEachTest.class 由反编类和汇编指令可以看到对于Iterable类,