xsi
- это пространство имен префикс , это не пространство имен. Единственное место, где префикс должен быть согласованным, находится внутри элемента XML, который его объявляет.
Префикс даже не обязательно должен быть согласованным в одном и том же документе XML, вы можете иметь одно и то же пространство имен, на которое ссылается любое количество различных префиксов в одном и том же документе.
It особенно не обязательно должно быть согласованным между документом XML и вашим кодом обработки XML, и вы не должны (читай: должны) писать какой-либо код, который принимает префикс или полагается на префикс.
Вот почему if "xsi:type" in Node.attrib:
не имеет смысла - предполагается, что префикс должен быть xsi
. xsi
может обычно использоваться для пространства имен http://www.w3.org/2001/XMLSchema-instance
, но это всего лишь соглашение, а не гарантия.
Документ XML может быть записан как
<test:myXML xmlns:test="http://com/my/namespace" xmlns:blah="http://www.w3.org/2001/XMLSchema-instance">
<Parent>
<Child1 blah:type="sample-type">
<GrandChild1>123</GrandChild1>
<GrandChild2>BranchName</GrandChild2>
</Child1>
<Child2 blah:type="sample-type2"></Child2>
</Parent>
</test:myXML>
, и это было бы точно так же .
Вот почему l xml использует URI пространства имен, а не префикс, когда он отображает узлы или в своем диалекте XPath - URI является важным Дело в том, что префикс эфемерный.
Вам необходимо определить карту пространства имен в вашей программе
nsmap = {
'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
}
и использовать эту карту при выборе узлов в пространстве имен - либо явно:
if f"{{{nsmap['xsi']}}}type" in node.attrib:
# ...
или через XPath
type = node.xpath('@xsi:type', nsmap)
Это делает вашу программу независимой от префикса - вы можете использовать любой префикс, который вам нравится, документ XML может использовать любой префикс, который ему нравится , и код будет работать в любом случае.
Экстремальный пример, но полезно изложить идею:
<test:myXML xmlns:test="http://com/my/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Parent xmlns:blah="http://www.w3.org/2001/XMLSchema-instance">
<Child1 foo:type="sample-type" xmlns:foo="http://www.w3.org/2001/XMLSchema-instance">
<GrandChild1>123</GrandChild1>
<GrandChild2>BranchName</GrandChild2>
</Child1>
<Child2 blah:type="sample-type2"></Child2>
</Parent>
</test:myXML>
Здесь http://www.w3.org/2001/XMLSchema-instance
получает 3 префикса. xsi
, blah
, foo
, каждый с разной областью действия.
Когда это будет проанализировано, какой из них вы будете использовать для ссылки на xsi
? Имеет ли это значение? Должно ли иметь значение? Нет, не должно. Все, что нужно для сопоставления, - это URI пространства имен, нам безразлично, что документ XML делает с префиксами:
nsmap = {
's': 'http://www.w3.org/2001/XMLSchema-instance'
}
type = node.xpath('@s:type', namespaces=nsmap)