你可以如何在使用lxml.etree.xmlfile()进行序列化时设置命名空间前缀?

huangapple go评论58阅读模式
英文:

How can I set the namespace prefix when serializing with lxml.etree.xmlfile()?

问题

我尝试按顺序编写一个非常大的 XML 文件。以下是一个最小的代码示例:

import lxml.etree as ET

ET.register_namespace('xsl', 'http://www.w3.org/1999/XSL/Transform')
with ET.xmlfile('../output/test.xml', encoding='utf-8') as xf:
    xf.write_declaration()
    with xf.element(ET.QName('http://www.w3.org/1999/XSL/Transform', 'root')):
        with xf.element('sub'):
            pass

我得到了以下输出:

<?xml version='1.0' encoding='utf-8'?>
<ns0:root xmlns:ns0="http://www.w3.org/1999/XSL/Transform">
    <sub>
    </sub>
</ns0:root>

我希望前缀是 xsl:...,但实际上得到了通用的 ns0:...。是否有人知道我需要在这里进行哪些调整?

英文:

I try to write a very big xml file sequentially.
Here is a minimal code example:

import lxml.etree as ET

ET.register_namespace(&#39;xsl&#39;, &#39;http://www.w3.org/1999/XSL/Transform&#39;)
with ET.xmlfile(&#39;../output/test.xml&#39;, encoding=&#39;utf-8&#39;) as xf:
     xf.write_declaration()
     with xf.element(ET.QName(&#39;http://www.w3.org/1999/XSL/Transform&#39;, &#39;root&#39;)):
         with xf.element(&#39;sub&#39;):
             pass

I get the follwing output.

&lt;?xml version=&#39;1.0&#39; encoding=&#39;utf-8&#39;?&gt;
&lt;ns0:root xmlns:ns0=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
     &lt;sub&gt;
     &lt;/sub&gt;
&lt;/ns0:root&gt;

I hoped the prefixes would be xsl:..., but instead got the generic ns0:... .
Does anbody know what I need to tweak here?

答案1

得分: 3

经过大量测试,我找到了正确的解决方案。需要在第一个元素上传递参数nsmap={tag: namespace},其中命名空间被使用。

import lxml.etree as ET

with ET.xmlfile('../output/test.xml', encoding='utf-8') as xf:
    xf.write_declaration()
    with xf.element(ET.QName('http://www.w3.org/1999/XSL/Transform', 'root'),
                    nsmap={'xsl': 'http://www.w3.org/1999/XSL/Transform'}):
        with xf.element('sub'):
            pass

具有相同命名空间的连续元素会自动从命名空间URI转换为标记表示法。然而,如果您始终传递nsmap参数,您将强制在每个元素上添加命名空间条目(xmlns:xsl="http://www.w3.org/1999/XSL/Transform")。

英文:

After a lot of testing I found the right solution. One needs to pass the argument nsmap={tag : namespace} on the first element, where the namespace is used.

import lxml.etree as ET

with ET.xmlfile(&#39;../output/test.xml&#39;, encoding=&#39;utf-8&#39;) as xf:
     xf.write_declaration()
     with xf.element(ET.QName(&#39;http://www.w3.org/1999/XSL/Transform&#39;, &#39;root&#39;),
                     nsmap={&#39;xsl&#39;: &#39;http://www.w3.org/1999/XSL/Transform&#39;}):
         with xf.element(&#39;sub&#39;):
             pass

Successive elements with the same namespace are automatically converted from namespace URI to tag notation. However, if you always pass the nsmap argument you would force a namespace entry on every element (xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;).

huangapple
  • 本文由 发表于 2023年6月19日 21:19:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76507041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定