处理指令中的实体得到更改

时间:2018-10-17 05:32:30

标签: xml xslt xslt-2.0

我有一个xml文件。

  1. 我正在将处理指令转换为元素。
  2. 属性中处理指令的补货值。
  3. 问题在处理指令中有一个实体正在变为 。
  4. 我希望实体保持原样。

             <element>
             <?comment adtxt="hello &#160; Guys"?>
            </element>
    

我的xslt代码:

        <xsl:template match="element">
        <xsl:copy>
        <xsl:apply-templates/>
        </xsl:copy>
        </xsl:template>
        <xsl:template match="processing-instruction(comment)">
        <inddq>
        <xsl:attribute name="adtxt">
        <xsl:value-of select="."/>
        </xsl:attribute>
        <xsl:processing-instruction name="comment">
        <xsl:value-of select="."/>
        </xsl:processing-instruction>
        </inddq>
        </xsl:template>

我得到的输出

    <element>
    <inddq adtxt="adtxt=&#34;hello &amp;#160; Guys&#34;">
    <?comment adtxt="hello &#160; Guys"?>
    </inddq>
    </element>

已经谢谢了,

1 个答案:

答案 0 :(得分:2)

这是一个棘手的问题,处理指令的内容未解析为XML,请参见https://www.w3.org/TR/REC-xml/#sec-pi

  

PI不属于文档字符数据

因此,如果您希望将内容解析为XML,就像您希望XML解析器解析XML字符引用,然后将其输出为&#160;,那么一个干净的解决方案将需要XSLT 3与

  1. parse-xml-fragment
  2. 使用角色图

所以

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

  <xsl:output use-character-maps="m1"/>

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

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

    <xsl:template match="processing-instruction(comment)">
            <inddq>
            <xsl:attribute name="adtxt">
            <xsl:value-of select="parse-xml-fragment(.)"/>
            </xsl:attribute>
            <xsl:processing-instruction name="comment">
            <xsl:value-of select="."/>
            </xsl:processing-instruction>
            </inddq>
    </xsl:template> 

</xsl:stylesheet>

将进行转换

<element>
         <?comment adtxt="hello &#160; Guys"?>
        </element>

使用诸如Saxon 9.8(https://xsltfiddle.liberty-development.net/eiZQaG3)或9.9或Altova 2017或2018的XSLT 3处理器

<element>
         <inddq adtxt='adtxt=&#34;hello &#160; Guys&#34;'><?comment adtxt="hello &#160; Guys"?></inddq>
        </element>

另一方面,这并不是在处理指令的数据内保留任何字符引用,它只是一种将其解析为XML,然后通过输出替换所有Unicode不间断空格字符的方式,以作为输出。字符映射,序列&#160;表示该字符的数字字符引用。

当然,该方法可以扩展到其他字符引用,但是在任何情况下,字符映射都将应用于任何输出字符,不可能仅将其限制为adtxt属性值。

作为使用XSLT / XPath 3函数parse-xml-fragment的替代方法,您可以使用replace,就像在https://xsltfiddle.liberty-development.net/eiZQaG3/1中所做的那样,但是仍然需要使用字符映射: https://xsltfiddle.liberty-development.net/eiZQaG3/1