如何阻止Oracle Dbms_XmlDom对属性值中的&进行转义?
如何阻止Oracle Dbms_XmlDom.setAttribute转义属性值中的&
问题分析
Dbms_XmlDom的setAttribute方法会自动对XML属性值中的特殊字符(如&、<、"等)进行转义,这是符合XML规范的行为——XML属性中&必须被转义为&。但如果需要保留原始的实体引用(如£),直接使用setAttribute无法实现,因为它会把输入的&转义成&,最终得到&#163;。
可行解决方案
要绕过自动转义,可通过以下两种方式实现:
方法1:使用createAttribute+setNodeValue直接操作属性节点
通过创建独立的属性节点并设置其值,可避免setAttribute的自动转义逻辑:
DECLARE doc_ dbms_XmlDom.DomDocument := Dbms_XmlDom.newDomDocument; nd_ dbms_XmlDom.DomNode; tag_ dbms_XmlDom.DomElement; attr_ dbms_XmlDom.DomAttr; data_in_ VARCHAR2(50) := '£'; out_ VARCHAR2(32000); BEGIN Dbms_XmlDom.setVersion (doc_, '1.0" encoding="UTF-8" standalone="yes'); tag_ := Dbms_XmlDom.createElement ( doc => doc_, tagName => 'coreProperties' ); -- 创建属性节点并直接设置值 attr_ := Dbms_XmlDom.createAttribute(doc_, 'myAttribute'); Dbms_XmlDom.setNodeValue(Dbms_XmlDom.makeNode(attr_), data_in_); Dbms_XmlDom.setAttributeNode(tag_, attr_); nd_ := Dbms_XmlDom.appendChild (Dbms_XmlDom.makeNode(doc_), Dbms_XmlDom.makeNode(tag_)); out_ := Dbms_XmlDom.getXmlType(doc_).getClobVal; Dbms_XmlDom.freeDocument (doc_); Dbms_Output.Put_Line (out_); END; /
方法2:直接构造XML字符串转换为DOM文档
如果场景允许,直接拼接符合要求的XML字符串再转为DOM,可完全控制属性内容:
DECLARE doc_ dbms_XmlDom.DomDocument; out_ VARCHAR2(32000); xml_str_ VARCHAR2(32000) := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' || '<coreProperties myAttribute="£"/>'; BEGIN doc_ := Dbms_XmlDom.newDomDocument(XmlType(xml_str_)); out_ := Dbms_XmlDom.getXmlType(doc_).getClobVal; Dbms_XmlDom.freeDocument (doc_); Dbms_Output.Put_Line (out_); END; /
关键补充说明
XML规范要求属性值中的&必须转义,&#163;是符合语法的正确表示,解析时会被还原为£(对应英镑符号£)。如果你的最终需求是让属性值解析为£字符,更合理的方式是直接输入字符£(确保环境编码为UTF-8),setAttribute会自动处理为合法的XML输出。
内容的提问来源于stack exchange,提问作者cartbeforehorse
相关产品推荐
相关产品推荐

