XML:从名称空间生成带有前缀的标签

奥马尔·冈萨雷斯

我需要使用代表名称空间的不同前缀来生成XML:

例如,我有以下名称空间列表:

class XMLNamespaces:
   empty="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
   cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" 
   cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
   ccts="urn:un:unece:uncefact:documentation:2" 
   ds="http://www.w3.org/2000/09/xmldsig#" 
   ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" 
   qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" 
   sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1" 
   udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" 
   xsi="http://www.w3.org/2001/XMLSchema-instance"
# create XML 

NSMAP={None:XMLNamespaces.empty, 'cac':XMLNamespaces.cac, 'cbc':XMLNamespaces.cbc,
        'ccts':XMLNamespaces.ccts, 'ds':XMLNamespaces.ds, 'ext':XMLNamespaces.ext,
        'qdt':XMLNamespaces.qdt, 'sac':XMLNamespaces.sac, 'udt':XMLNamespaces.udt,
        'xsi':XMLNamespaces.xsi}

我想生成以下结构:

只有Invoice标签具有完整的名称空间。

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" 
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
xmlns:ccts="urn:un:unece:uncefact:documentation:2" 
xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" 
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" 
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1" 
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ext:UBLExtensions>
     <ext:UBLExtension>
         <ext:ExtensionContent>
            <sac:AdditionalInformation>
            </sac:AdditionalInformation>
         </ext:ExtensionContent>
     </ext:UBLExtension>
</Invoice>

我的代码:

from lxml import etree
from lxml.etree import Element, SubElement, QName, tostring

class XMLNamespaces:
   empty="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
   cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" 
   cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
   ccts="urn:un:unece:uncefact:documentation:2" 
   ds="http://www.w3.org/2000/09/xmldsig#" 
   ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" 
   qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" 
   sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1" 
   udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" 
   xsi="http://www.w3.org/2001/XMLSchema-instance"


NSMAP={None:XMLNamespaces.empty, 'cac':XMLNamespaces.cac, 'cbc':XMLNamespaces.cbc,
        'ccts':XMLNamespaces.ccts, 'ds':XMLNamespaces.ds, 'ext':XMLNamespaces.ext,
        'qdt':XMLNamespaces.qdt, 'sac':XMLNamespaces.sac, 'udt':XMLNamespaces.udt,
        'xsi':XMLNamespaces.xsi}


invoice = etree.Element("Invoice", nsmap=NSMAP) # lxml only!
ublextensions = etree.SubElement(invoice, "UBLExtensions", nsmap=NSMAP['ext'])

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

但它返回:

File "xml-building.py", line 27, in <module>
    ublextensions = etree.SubElement(invoice, "UBLExtensions", nsmap=NSMAP['ext'])
  File "src\lxml\etree.pyx", line 3135, in lxml.etree.SubElement
  File "src\lxml\apihelpers.pxi", line 199, in lxml.etree._makeSubElement
  File "src\lxml\apihelpers.pxi", line 193, in lxml.etree._makeSubElement
  File "src\lxml\apihelpers.pxi", line 213, in lxml.etree._setNodeNamespaces
  File "src\lxml\apihelpers.pxi", line 274, in lxml.etree._iter_nsmap
TypeError: 'in <string>' requires string as left operand, not NoneType
冈萨雷斯(JC Gonzalez)

您无需nsmap在子元素中添加删除该名称并在每个元素的ID之前的大括号中添加所需的名称空间(请参见下文,为此我使用了另外的字典)。它将根据您的需要工作:

from lxml import etree
from lxml.etree import Element, SubElement, QName, tostring

class XMLNamespaces:
   empty="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
   cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
   cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
   ccts="urn:un:unece:uncefact:documentation:2"
   ds="http://www.w3.org/2000/09/xmldsig#"
   ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
   qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
   sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
   udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
   xsi="http://www.w3.org/2001/XMLSchema-instance"

NSMAP={None:XMLNamespaces.empty, 'cac':XMLNamespaces.cac, 'cbc':XMLNamespaces.cbc,
        'ccts':XMLNamespaces.ccts, 'ds':XMLNamespaces.ds, 'ext':XMLNamespaces.ext,
        'qdt':XMLNamespaces.qdt, 'sac':XMLNamespaces.sac, 'udt':XMLNamespaces.udt,
        'xsi':XMLNamespaces.xsi}

ns = {k:'{' + v + '}' for k,v in NSMAP.items()}

invoice = etree.Element("Invoice", nsmap=NSMAP) # lxml only!
ublextensions = etree.SubElement(invoice, f"{ns['ext']}UBLExtensions")
ublextension = etree.SubElement(ublextensions, f"{ns['ext']}UBLExtension")
extcontent = etree.SubElement(ublextension, f"{ns['ext']}ExtensionContent")
addinfo = etree.SubElement(extcontent, f"{ns['sac']}AdditionalInformation")

print(etree.tostring(invoice, pretty_print=True).decode('ascii'))

结果:

<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
 xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
 xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
 xmlns:ccts="urn:un:unece:uncefact:documentation:2"
 xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
 xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
 xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
 xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
 xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <ext:UBLExtensions>
    <ext:UBLExtension>
      <ext:ExtensionContent>
        <sac:AdditionalInformation/>
      </ext:ExtensionContent>
    </ext:UBLExtension>
  </ext:UBLExtensions>
</Invoice>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在JAVA中编码默认名称空间和带有单个XML元素前缀的名称空间

更改使用JAXWS生成的默认XML名称空间前缀

在具有名称空间前缀的元素内创建不带名称空间前缀的XML元素

XSLT在Saxon中生成带有未声明的名称空间前缀的输出。错误XTSE1430:未声明命名空间前缀exsl

添加不带名称空间的带有前缀的开始元素

从外壳程序向XML文档的默认名称空间的标签添加名称空间前缀。

XML中是否可以有多个名称空间前缀?

如何将带有命名空间的标签更改为带有默认命名空间前缀的标签

在 *value* 中带有前缀的 XML 属性 - 如何判断它是命名空间前缀?

从可能带有或不带有氏族标签前缀的名称中获取实名

使用lxml解析xml时,在标签中保留名称空间前缀

如何在不带前缀的情况下使用某些XML名称空间标签?

XML名称空间前缀冲突的XPath行为

XML更改带有标签内容的标签名称

如何在PHP中使用SimpleXMLElement生成以名称空间为前缀的xml元素

SPARQL查询以获取定义了名称空间前缀的所有类标签

如何在 PHP Xpath 中获取带有命名空间前缀的元素名称

如何选择带有名称空间的XML节点

在解析带有XDocument的XML时无法解析名称空间

不读取带有名称空间的XML元素

带有多个名称空间的jqGrid xml解析

使用带有lxml的嵌套名称空间解析XML属性

解析带有名称空间的xml文件时出错

Spring soap ws 未运行,请求在 xml 标签中没有命名空间前缀

访问没有命名空间前缀的 XML 中的特定标签属性

Azure Logic应用-具有名称空间前缀的xml的xpath

XML XSLT 转换:将带有前缀的命名空间添加到 rss 元素

python:带有前缀“。”的模块名称

LXML名称空间前缀