XSL:转义CDATA并将其解析为xml,其中包含for-each

XSL:转义CDATA并将其解析为xml,其中包含for-each,xml,xslt,cdata,Xml,Xslt,Cdata,我有一个xml文档(输入文件不能更改),我需要用xsl将其转换为另一个xml。输入xsl具有CDATA,如以下示例结构所示: <TestCaseElement> <Role>VP</Role> <Code> <Line> <![CDATA[<id>l1_SomeId1</id> <val1>l1_SomeVal1</val1>

我有一个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>

副总裁

l1_SomeId1 l1_SomeVal1 l1_SomeVal2 l1_somealgo]>
l2_someid1 l2_SomeVal1 l2_SomeVal2 l2_somealgo]>

预期结果如下:

<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中的标记。如何为每个应用某种禁用输出转义?或者任何其他方法来解决这个问题?

考虑使用XSLT 3.0(由Saxon 9.8和Altova XMLSpy/Raptor支持)和
parse-xml-fragment()

考虑使用XSLT 3.0(由Saxon 9.8和Altova XMLSpy/Raptor支持)和
parse-xml-fragment()


您将使用哪个XSLT处理器?该处理器位于名为“MBT套件”的程序中。但是看一下about页面,我发现上面写着“Saxon HE 9.5.1”。我假设这是XSLT处理器,检查Saxon文档,看看是否支持将字符串解析为XML作为扩展。否则,您需要在两个过程中执行此操作,第一个过程执行DOE并将结果保存到文件中。您是对的,似乎我需要执行两个过程,有没有关于如何执行此操作的示例?我已经尝试创建中间文件。问题是我不能在同一个转换中写入和读取中间文件(XTRE1500错误)。您必须使用两个样式表执行两个转换。希望您的应用程序能够自动执行此操作。-这里真正的问题是您的数据源;如果他们希望您解析数据,他们不会将其作为CDATA提供。您将使用哪个XSLT处理器?该处理器位于名为“MBT套件”的程序中。但是看一下about页面,我发现上面写着“Saxon HE 9.5.1”。我假设这是XSLT处理器,检查Saxon文档,看看是否支持将字符串解析为XML作为扩展。否则,您需要在两个过程中执行此操作,第一个过程执行DOE并将结果保存到文件中。您是对的,似乎我需要执行两个过程,有没有关于如何执行此操作的示例?我已经尝试创建中间文件。问题是我不能在同一个转换中写入和读取中间文件(XTRE1500错误)。您必须使用两个样式表执行两个转换。希望您的应用程序能够自动执行此操作。-这里真正的问题是您的数据源;如果他们想让你解析数据,他们不会将其作为CDATA提供。非常感谢,我将尝试以这种方式实现。首先,我需要检查我的处理器是否支持XML3.0。输入有错误。您是对的,这只是一个exmaple,不是真正的输入。还是谢谢你!我试过XMLSpy,正在工作,非常感谢。不幸的是,我的处理器不支持XML3.0或任何扩展(即使是saxon)(它说它使用saxon HE 9.5.1,但我不确定)。我在考虑制作一个中间文档,也许可以。非常感谢,我将尝试以这种方式实现。首先,我需要检查我的处理器是否支持XML3.0。输入有错误。您是对的,这只是一个exmaple,不是真正的输入。还是谢谢你!我试过XMLSpy,正在工作,非常感谢。不幸的是,我的处理器不支持XML3.0或任何扩展(即使是saxon)(它说它使用saxon HE 9.5.1,但我不确定)。我在考虑制作一个中间文档,也许可以。
<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>