Пространства имен в lxml - PullRequest
       7

Пространства имен в lxml

0 голосов
/ 04 марта 2020

Я хочу создать следующий XML с пакетом lxml:

<configuration xmlns:cond="http://www.aaa.com/orc/condition" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../schema/variation-config.xsd">
   <strategy id="XXX">
       <conditions>
          <cond:scenario>A</cond:scenario>
       </conditions>
   </strategy>
</configuration>

Пока у меня есть следующий код, который совсем не подходит:

XHTML_NAMESPACE = "http://www.aaa.com/orc/condition"
XHTML = "{%s}" % XHTML_NAMESPACE
NSMAP = {
    'cond' : XHTML_NAMESPACE,
    'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
}
root = etree.Element(
    "configuration",
    nsmap=NSMAP,
)
strategy = etree.SubElement(root, "strategy", id="XXX")
conditions = etree.SubElement(strategy, "conditions")
cond1 = etree.SubElement(conditions, XHTML + "scenario", nsmap=NSMAP)
cond1.text = "A"

Это дает мне следующее:

<configuration xmlns:cond="http://www.aaa.com/orc/condition" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <strategy id="XXX">
    <conditions>
      <cond:scenario>A</cond:scenario>
    </conditions>
  </strategy>
</configuration>

Вопрос:

Я просто скучаю по xsi:noNamespaceSchemaLocation="../schema/variation-config.xsd". Вы знаете, как я мог бы добавить это к XML?

1 Ответ

2 голосов
/ 04 марта 2020

После того, как вы обновили свой вопрос с лучшим решением, я думаю, что вам не хватает способа установить атрибут для существующего элемента. Используйте метод set:

root.set(XSI + "noNamespaceSchemaLocation", "../schema/variation-config.xsd")

Кроме того, когда вы добавляете подэлемент к элементу, который уже знает пространства имен, определенные в nsmap, нет необходимости снова включать nsmap. Другими словами, вместо

cond1 = etree.SubElement(conditions, XHTML + "scenario", nsmap=NSMAP)

вы можете написать

cond1 = etree.SubElement(conditions, XHTML + "scenario")

Наконец, XHTML - неудачное имя переменной, поскольку X HTML - стандартное пространство имен.

Решение, которое дает правильный результат

from lxml import etree

COND_NAMESPACE = "http://www.aaa.com/orc/condition"
XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance"

COND = "{%s}" % COND_NAMESPACE
XSI = "{%s}" % XSI_NAMESPACE

nsmap = {"cond": "http://www.aaa.com/orc/condition", "xsi": "http://www.w3.org/2001/XMLSchema-instance"}

root = etree.Element("configuration", nsmap=nsmap)
root.set(XSI + "noNamespaceSchemaLocation", "../schema/variation-config.xsd")

strategy = etree.SubElement(root, "strategy", id="XXX")

conditions = etree.SubElement(strategy, "conditions")
scenario = etree.SubElement(conditions, COND + "scenario")

scenario.text = "A"

print(etree.tostring(root, pretty_print=True))

Выход

<configuration xmlns:cond="http://www.aaa.com/orc/condition" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../schema/variation-config.xsd">
  <strategy id="XXX">
    <conditions>
      <cond:scenario>A</cond:scenario>
    </conditions>
  </strategy>
</configuration>
...