使用 XSL 转换将“&”转换为“&”,但抛出错误为“et.sf.saxon.event.NoOpenStartTagException:”

converting `&` to `&` using xsl transformation but an error is thrown as "et.sf.saxon.event.NoOpenStartTagException: "

提问人:Rahul 提问时间:5/16/2023 最后编辑:Rahul 更新时间:5/16/2023 访问量:66

问:

我们正在使用 XSL 转换器将 hexcode 实体转换为 mdash。这种转换按预期发生。 但是我们还必须将 xml 中的所有内容转换为输出为 &。 现在,输出包含 . 在 xsl 转换期间,显示以下错误:-&&

不能在包含元素的子元素之后创建属性节点。

使用以下 xsl 时,会抛出错误:-


<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >
<xsl:output method="xml" omit-xml-declaration="no" use-character-maps="mdash" />
<xsl:character-map name="mdash">
<xsl:output-character character="&#x2014;" string="&amp;mdash;" />
</xsl:character-map>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:text disable-output-escaping="yes">&amp;</xsl:text>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XSLT XML 解析 Saxon Saxparser xalan

评论

0赞 michael.hor257k 5/16/2023
如果您使用的是 Saxon,请不要将您的问题标记为 .xalan

答:

0赞 Martin Honnen 5/16/2023 #1

你有一个匹配的模板,在模板中,你做了一个浅拷贝,然后,你创建一个文本节点,作为第一个子节点,然后期望进一步处理属性节点(和子节点),即复制它们,这对属性节点不起作用,因为一旦你输出了那个子节点, 您无法添加属性节点。match="@* | node()"xsl:copy<xsl:text disable-output-escaping="yes">&amp;</xsl:text><xsl:apply-templates select="@*|node()" />

我还没有真正理解你需要什么,但你不能输出一个子节点,然后尝试输出一个属性节点;首先处理属性节点,然后创建和/或处理子节点。xsl:text

至于“将 xml 中的所有内容转换为输出”以及“将十六进制实体转换为 mdash”的任务,我想您想要例如&amp;&

<xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  
<xsl:output method="xml" omit-xml-declaration="no" use-character-maps="mdash amp" />

<xsl:character-map name="mdash">
  <xsl:output-character character="&#x2014;" string="&amp;mdash;" />
</xsl:character-map>

<xsl:character-map name="amp">
  <xsl:output-character character="&amp;" string="&amp;" />
</xsl:character-map>

<xsl:mode on-no-match="shallow-copy"/>

</xsl:stylesheet>

评论

0赞 Rahul 5/16/2023
这个成功了。多谢。请问,浅拷贝部分在这里做什么,以及为什么我们直接使用 string=“&” 而不是 &。
0赞 Martin Honnen 5/16/2023
这是 XSLT 3.0 的声明性方法,用于将标识转换设置为基本模板,因此您不必拼写出常用的(XSLT 2 或 1)模板来执行 和 处理内部的属性和子节点。<xsl:mode on-no-match="shallow-copy"/>match="@* | node()"xsl:copy<xsl:apply-templates select="@* | node()"/>
0赞 Martin Honnen 5/16/2023
XSLT 是 XML,因此它必须在其程序代码中遵循 XML 语法规则,因此,在输出树序列化时,序列化程序应将任何字符按字面意思输出为字符,而不是强制将 XML 序列化作为 .<xsl:output-character character="&amp;" string="&amp;" />&&&amp;
1赞 Michael Kay 5/16/2023
值得补充的是,如果采用此解决方案,则无法保证转换的结果将是格式正确的 XML。