使用XSLT转换XML时保留实体引用?
发布时间:2020-12-16 07:49:48 所属栏目:百科 来源:网络整理
导读:在使用XSLT(2.0)转换 XML时,如何保留实体引用?使用我尝试过的所有处理器,默认情况下实体都会被解析.我可以使用xsl:character-map来处理字符实体,但是文本实体呢? 例如,这个XML: !DOCTYPE doc [!ENTITY so "stackoverflow"!ENTITY question "How can I pr
在使用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. 谢谢!
如果您知道将使用哪些实体以及如何定义它们,您可以执行以下操作(相当原始且容易出错,但仍然比没有更好):
<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架构和处理模型的原则 – 换句话说,这个解决方案是一个讨厌的黑客. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |