【发布时间】:2018-10-24 00:03:22
【问题描述】:
如果重新声明命名空间定义,您如何获得正确的命名空间?详细说明:前缀相同但属性值不同,因此重新声明。
即<site:Stack xmlns:site='http://stackoverflow.com'>
至
<site:Stack xmlns:site='https://math.stackexchange.com/'>
根据我在 Microsoft 的 XML 文档中读到的内容,这是可以接受的,它只是 重新声明命名空间。 除非这是不被接受的形式,然后我可以关闭这个问题。
这是一个问题,因为它弄乱了大多数字典获取命名空间的方法,但它也弄乱了标准库中的 ElementTree.register_namespace(prefix, uri) 方法。
Register_namespace 非常重要,因为它用于解析命名空间标签,因为 ET 解析以 clark 表示法给出标签,例如 Header 元素,如
<{http://schemas.xmlsoap.org/soap/envelope/}:Header/>
使用 register_namespace 将上述解析回<SOAP-ENV:Header/>。
这给我带来了严重的问题,因为我将 XML 反序列化为自定义类对象,然后(经过一些处理/编辑)重新序列化为格式良好的 XML 文件。
即来自 Oracle 的 XML 示例。 请注意 Orders 如何更改为 Confirm,但前缀相同。
<PO:order xmlns:PO="http://gizmos.com/orders/"> 更改为
<PO:confirmation xmlns:PO="http://gizmos.com/confirm">
<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring>Message does not have necessary info</faultstring>
<faultactor>http://gizmos.com/order</faultactor>
<detail>
<PO:order xmlns:PO="http://gizmos.com/orders/">
Quantity element does not have a value
</PO:order>
<PO:confirmation xmlns:PO="http://gizmos.com/confirm">
Incomplete address: no zip code
</PO:confirmation>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
请注意:我知道您可以使用以下方法获取带有命名空间的字典。但这将使用任何命名空间的最新声明。同样 ET.register_namespace 也会这样做,这是使用最近的声明。
import xml.etree.ElementTree as ET
my_namespaces = dict([
node for (_, node) in ET.iterparse('file.xml', events=['start-ns'])
])
【问题讨论】:
-
据我所知,对两个不同的命名空间 URI 使用相同的前缀是合法的。见stackoverflow.com/q/41774652/407651。
-
从那个答案看来,Oracle 给出的上述 XML 实际上是无效的。您链接的答案表明 NameSpace 允许相同,但最终 Xpath Mapping 必须是唯一的。所以在我的例子中,PO 不能同时映射到 Order 和 Confirmation。
-
我不认为您的 XML 示例是“无效的”。我已经使用 Python 的 ElementTree 模块以及 xmllint 对其进行了解析,并且没有错误。
-
我知道它的“有效”但格式正确是另一个我不确定的问题。就像我在原始帖子中提到的那样, register_namespace 不起作用。我已将其作为 ET 读入,将其分解,然后重新序列化回 ET。然而就像我之前说的,标准库函数调用不能使用它,因为有两个重复的前缀 PO。即使在您链接到我的答案中,答案也明确提到每个映射都必须是唯一的。
-
文档格式正确。如果不是,解析器会抛出错误。我想说的是,对于两个不同的命名空间使用相同的前缀是不寻常的(并且令人困惑),但它不会违反 XML 文档的任何规则。
标签: python xml elementtree