Replacing and maintaining character entities throu

2019-07-08 08:15发布

问题:

Problem: We have character entities come to our systems in various formats (Ex: & and &) and we need to convert them to a standard XML character entities if needed (&amp < > ' ") and then maintain them as entities through a couple of separate tranformations.

Given XML of:

<rootelm>
 <testdata>&amp;apos; &amp;gt; &amp;lt; &amp;quot;</testdata>
</rootelm>

and a stylesheet of (based on xsl:character-map to replace special characters):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
 <!-- COPY EVERYTHING -->
 <xsl:template match="node() | @*">
  <xsl:copy>
   <xsl:apply-templates select="@* | node()">
    <xsl:sort select="local-name()"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
 <xsl:variable name="quote">
  <xsl:text>&amp;quot;</xsl:text>
 </xsl:variable>
 <xsl:variable name="quote2">
  <xsl:value-of select="string('&quot;')"/>
 </xsl:variable>
 <xsl:template match="text()[contains(.,'&amp;lt;') or contains(.,'&amp;gt;') or contains(.,'&amp;quot;') or contains(.,'&amp;apos;')]">
  <xsl:value-of select='replace(
  replace(
   replace(
    replace(., "&amp;lt;", "&lt;"),
   "&amp;gt;",
   "&gt;"
   ),
  "&amp;apos;",
  "&apos;"
  ),
  $quote,
  $quote2
 )
    ' />
 </xsl:template>
</xsl:stylesheet>

How can I keep the apostrophe's and quotes as entities (source system expects/needs it)?

Current Output:

<rootelm> 
   <testdata>' &gt; &lt; "</testdata>
</rootelm>

回答1:

Use Character Maps :

[Definition: A character map allows a specific character appearing in a text or attribute node in the final result tree to be substituted by a specified string of characters during serialization.]

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