XML实体定义中转义字符引用时被还原,如何解决验证失败问题?
解决XML实体存储含特殊字符SQL查询的验证问题
问题根源
XML解析顺序是先替换实体引用,再处理属性值的转义字符。你原来的实体定义中用了&lt;(双重转义),替换后属性值变成SELECT * FROM my_table WHERE type<>9,随后XML解析器会把<转成<,而<在XML属性值中属于非法字符,直接导致验证失败。
适配遗留系统的解决方案
需要让实体替换后的属性值保留合法的XML转义格式,同时最终能被应用程序解析出正确的SQL。以下两种方法无需修改系统架构:
方法1:双重转义实体内容
在实体定义中对特殊字符进行双重转义,确保实体替换后属性值中的转义码不会被XML解析器直接解析为原始特殊字符:
<!ENTITY SQL.typeNot9 "SELECT * FROM my_table WHERE type&amp;lt;&amp;gt;9"> <item name="endFixId" browseType="database" form="example_form" SQLQuery="&SQL.typeNot9;" useRawValue="false" />
- 解析流程:
- 实体替换后,属性值变为
SELECT * FROM my_table WHERE type&lt;&gt;9 - XML解析器处理属性值,将
&转成&,最终得到合法的属性值:SELECT * FROM my_table WHERE type<>9 - 应用程序读取属性值后,再执行一次转义解码,将
<转成<、>转成>,即可得到正确的SQL语句。
- 实体替换后,属性值变为
方法2:使用数值字符引用
在实体定义中直接使用特殊字符的数值字符引用,避免预定义实体的二次解析:
<!ENTITY SQL.typeNot9 "SELECT * FROM my_table WHERE type&#60;&#62;9"> <item name="endFixId" browseType="database" form="example_form" SQLQuery="&SQL.typeNot9;" useRawValue="false" />
- 解析流程:
- 实体替换后,属性值变为
SELECT * FROM my_table WHERE type&#60;&#62;9 - XML解析器处理属性值,将
&转成&,最终得到合法的属性值:SELECT * FROM my_table WHERE type<>9 - 应用程序解码字符引用,即可得到
type<>9的SQL逻辑。
- 实体替换后,属性值变为
验证测试
修改后重新执行xmllint --schema my_schema.xsd my.xml,不会再出现<字符非法的错误提示。
内容的提问来源于stack exchange,提问作者user21397135
相关产品推荐
相关产品推荐

