XML默认命名空间与命名空间前缀的正确使用方法咨询
解决XML命名空间导致解析器失效的两种方案
同事为遵循最佳实践,给XML payload里的每个元素都加了ns0命名空间前缀,结果我的解析器没法正常工作。查资料发现不用给每个元素都声明命名空间,在根元素设置默认命名空间就能简化结构,具体处理方式分两种:
方案一:修改XML为默认命名空间格式
把根元素的命名空间声明改为默认命名空间,同时去掉所有元素的ns0:前缀,这样所有未加前缀的元素都会自动归属到默认命名空间下,既符合规范又能让解析器正常工作。
原XML:
<ns0:Root xmlns:ns0="urn:asw:erT" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:asw:erT"> <ns0:Ticket xmlns:urn="urn:asw:erT" Code="TEST" Key="1"> <ns0:client> <ns0:CardNumber>12345</ns0:CardNumber> <ns0:OpenPointsBalance>14352</ns0:OpenPointsBalance> <ns0:PointsEarnedValue>46</ns0:PointsEarnedValue> <ns0:PointsClosingBalance>14398</ns0:PointsClosingBalance> </ns0:client> </ns0:Ticket> </ns0:Root>
修改后的XML(优化重复声明):
<Root xmlns="urn:asw:erT" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <Ticket Code="TEST" Key="1"> <client> <CardNumber>12345</CardNumber> <OpenPointsBalance>14352</OpenPointsBalance> <PointsEarnedValue>46</PointsEarnedValue> <PointsClosingBalance>14398</PointsClosingBalance> </client> </Ticket> </Root>
注:默认命名空间仅作用于元素,不影响属性,所以
Code、Key这类属性无需做任何修改。
方案二:调整解析器适配带前缀的命名空间
如果XML是外部系统生成的,无法修改结构,那就需要调整解析器的配置,让它正确识别ns0前缀对应的命名空间urn:asw:erT。
举个简单例子:
- 用XPath查询时,需要先绑定
ns0到urn:asw:erT,再用//ns0:Ticket/ns0:client/ns0:CardNumber这样的路径查询元素; - 在Python的lxml库中,需要通过
namespaces参数指定前缀与命名空间的映射; - 在Java的DOM解析中,需要使用
NamespaceContext来关联前缀和命名空间。
这种方式不需要修改XML,只需要让解析器正确处理命名空间前缀即可。
内容的提问来源于stack exchange,提问作者David Garcia
相关产品推荐
相关产品推荐

