在使用XSLT(2.0)转换
XML时,如何保留实体引用?使用我尝试过的所有处理器,默认情况下实体都会被解析.我可以使用xsl:character-map来处理字符实体,但是文本实体呢?
例如,这个XML:
<!DOCTYPE doc [ <!ENTITY so "stackoverflow"> <!ENTITY question "How can I preserve the entity reference when transforming with XSLT??"> ]> <doc> <text>Hello &so;!</text> <text>&question;</text> </doc>
使用以下XSLT进行转换:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
产生以下输出:
<doc> <text>Hello stackoverflow!</text> <text>How can I preserve the entity reference when transforming with XSLT??</text> </doc>
输出应该看起来像输入(减去现在的doctype声明):
<doc> <text>Hello &so;!</text> <text>&question;</text> </doc>
我希望我不需要用& amp;替换所有的&符号来预处理输入. (比较& amp;问题;)然后通过替换所有& amp; amp后处理输出与& ;.
也许这是处理器特定的?我正在使用Saxon 9.
谢谢!
如果您知道将使用哪些实体以及如何定义它们,您可以执行以下操作(相当原始且容易出错,但仍然比没有更好):
原文链接:https://www.f2er.com/xml/292625.html<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:character-map name="mapEntities"> <xsl:output-character character="&" string="&"/> </xsl:character-map> <xsl:variable name="vEntities" select= "'stackoverflow','How can I preserve the entity reference when transforming with XSLT\?\?' "/> <xsl:variable name="vReplacements" select= "'&so;','&question;'"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="/"> <xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE doc [ <!ENTITY so "stackoverflow"> <!ENTITY question "How can I preserve the entity reference when transforming with XSLT??"> ]> ]]> </xsl:text> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"> <xsl:value-of select= "my:multiReplace(.,$vEntities,$vReplacements,count($vEntities) ) " disable-output-escaping="yes"/> </xsl:template> <xsl:function name="my:multiReplace"> <xsl:param name="pText" as="xs:string"/> <xsl:param name="pEnts" as="xs:string*"/> <xsl:param name="pReps" as="xs:string*"/> <xsl:param name="pCount" as="xs:integer"/> <xsl:sequence select= "if($pCount > 0) then my:multiReplace(replace($pText,$pEnts[1],$pReps[1] ),subsequence($pEnts,2),subsequence($pReps,$pCount -1 ) else $pText "/> </xsl:function> </xsl:stylesheet>
当应用于提供的XML文档时:
<!DOCTYPE doc [ <!ENTITY so "stackoverflow"> <!ENTITY question "How can I preserve the entity reference when transforming with XSLT??"> ]> <doc> <text>Hello &so;!</text> <text>&question;</text> </doc>
产生了想要的结果:
<!DOCTYPE doc [ <!ENTITY so "stackoverflow"> <!ENTITY question "How can I preserve the entity reference when transforming with XSLT??"> ]> <doc> <text>Hello &so;!</text> <text>&question;</text> </doc>
请注意:
>必须转义替换中的特殊(RegEx)字符.>我们需要解决DOE,这是不推荐的,因为它违反了XSLT架构和处理模型的原则 – 换句话说,这个解决方案是一个讨厌的黑客.