我有一个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内的标签。如何为每个应用一种禁用输出转义?或者任何其他解决方法?
答案 0 :(得分:0)
考虑使用XSLT 3.0(由Saxon 9.8和Altova XMLSpy / Raptor支持)和parse-xml-fragment()
:
<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>
请注意,在您发布的示例中,一个转义标记<![CDATA[<id>l2_someid1</id> <val1>l2_SomeVal1<val1> <val2>l2_SomeVal2<val2> <algo>l2_somealgo</algo>]]>
包含格式错误的标记,其中val1
和val2
未正确关闭,因此上述代码会因输入失败或您需要使用try/catch
以捕获任何解析错误:
<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>