5

I am creating a new xml file from scratch using python and the lxml library.

<route xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.xxxx" version="1.1"
xmlns:stm="http://xxxx/1/0/0"
xsi:schemaLocation="http://xxxx/1/0/0 stm_extensions.xsd">

I need to include this namespace information into the root tag as attributes of the route tag.

I can´t include the information into the root declaration.

from lxml import etree
root = etree.Element("route",
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance",
    xmlns = "http://www.xxxxx",
    version = "1.1",
    xmlns: stm = "http://xxxxx/1/0/0"
)

there is a SyntaxError: invalid syntax

How can I do that ?

mzjn
  • 48,958
  • 13
  • 128
  • 248
kamome
  • 828
  • 3
  • 11
  • 27
  • Possible duplicate of [Python: namespaces in xml ElementTree (or lxml)](https://stackoverflow.com/questions/4886189/python-namespaces-in-xml-elementtree-or-lxml) – stovfl Sep 25 '17 at 18:04
  • @stovfl: I don't think it is a duplicate. This question is about creating a new XML document; the other one is about parsing/manipulating an existing document. – mzjn Sep 25 '17 at 19:44

1 Answers1

8

Here is how it can be done:

from lxml import etree

attr_qname = etree.QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation")
nsmap = {None: "http://www.xxxx",
         "stm": "http://xxxx/1/0/0",
         "xsi": "http://www.w3.org/2001/XMLSchema-instance"}

root = etree.Element("route", 
                     {attr_qname: "http://xxxx/1/0/0 stm_extensions.xsd"},
                     version="1.1", 
                     nsmap=nsmap)

print etree.tostring(root)

Output from this code (line breaks have been added for readability):

<route xmlns:stm="http://xxxx/1/0/0"
       xmlns="http://www.xxxx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xxxx/1/0/0 stm_extensions.xsd"
       version="1.1"/>

The main "trick" is to use QName to create the xsi:schemaLocation attribute. An attribute with a colon in its name cannot be used as the name of a keyword argument.

I've added the declaration of the xsi prefix to nsmap, but it can actually be omitted. lxml defines default prefixes for some well-known namespace URIs, including xsi for http://www.w3.org/2001/XMLSchema-instance.

mzjn
  • 48,958
  • 13
  • 128
  • 248