Reputation: 461
I have an xml file.
I want entity remain as it is.
<element>
<?comment adtxt="hello   Guys"?>
</element>
My xslt code:
<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>
and output i am getting
<element>
<inddq adtxt="adtxt="hello &#160; Guys"">
<?comment adtxt="hello   Guys"?>
</inddq>
</element>
Already Thanks,
Upvotes: 0
Views: 164
Reputation: 167571
This is a tricky issue, the contents of a processing instruction is not parsed as XML, see https://www.w3.org/TR/REC-xml/#sec-pi saying
PIs are not part of the document's character data
so if you want to parse that contents as XML as you seem to want to have the XML character reference interpreted by an XML parser and later being output as  
then a clean solution would need XSLT 3 with
So
<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=" " string="&#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>
would transform
<element>
<?comment adtxt="hello   Guys"?>
</element>
with an XSLT 3 processor like Saxon 9.8 (https://xsltfiddle.liberty-development.net/eiZQaG3) or 9.9 or Altova 2017 or 2018 to
<element>
<inddq adtxt='adtxt="hello   Guys"'><?comment adtxt="hello   Guys"?></inddq>
</element>
On the other hand, that is not a preservation of any character reference inside the processing instruction's data, it is just a way to parse that as XML and then, for the output, to replace any Unicode non breaking space character through the character map with the sequence  
representing a numeric character reference of that character.
Of course the approach can be extended to other character references but in any case the character map will be applied to any output character, it is not possible to restrict it just to the adtxt
attribute value.
As an alternative to the use of the XSLT/XPath 3 function parse-xml-fragment you could use replace
, as done in https://xsltfiddle.liberty-development.net/eiZQaG3/1, but that still needs the use of the character map: https://xsltfiddle.liberty-development.net/eiZQaG3/1
Upvotes: 4