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

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

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

问题

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

  1. import lxml.etree as ET
  2. ET.register_namespace('xsl', 'http://www.w3.org/1999/XSL/Transform')
  3. with ET.xmlfile('../output/test.xml', encoding='utf-8') as xf:
  4. xf.write_declaration()
  5. with xf.element(ET.QName('http://www.w3.org/1999/XSL/Transform', 'root')):
  6. with xf.element('sub'):
  7. pass

我得到了以下输出:

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

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

英文:

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

  1. import lxml.etree as ET
  2. ET.register_namespace(&#39;xsl&#39;, &#39;http://www.w3.org/1999/XSL/Transform&#39;)
  3. with ET.xmlfile(&#39;../output/test.xml&#39;, encoding=&#39;utf-8&#39;) as xf:
  4. xf.write_declaration()
  5. with xf.element(ET.QName(&#39;http://www.w3.org/1999/XSL/Transform&#39;, &#39;root&#39;)):
  6. with xf.element(&#39;sub&#39;):
  7. pass

I get the follwing output.

  1. &lt;?xml version=&#39;1.0&#39; encoding=&#39;utf-8&#39;?&gt;
  2. &lt;ns0:root xmlns:ns0=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
  3. &lt;sub&gt;
  4. &lt;/sub&gt;
  5. &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},其中命名空间被使用。

  1. import lxml.etree as ET
  2. with ET.xmlfile('../output/test.xml', encoding='utf-8') as xf:
  3. xf.write_declaration()
  4. with xf.element(ET.QName('http://www.w3.org/1999/XSL/Transform', 'root'),
  5. nsmap={'xsl': 'http://www.w3.org/1999/XSL/Transform'}):
  6. with xf.element('sub'):
  7. 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.

  1. import lxml.etree as ET
  2. with ET.xmlfile(&#39;../output/test.xml&#39;, encoding=&#39;utf-8&#39;) as xf:
  3. xf.write_declaration()
  4. with xf.element(ET.QName(&#39;http://www.w3.org/1999/XSL/Transform&#39;, &#39;root&#39;),
  5. nsmap={&#39;xsl&#39;: &#39;http://www.w3.org/1999/XSL/Transform&#39;}):
  6. with xf.element(&#39;sub&#39;):
  7. 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:

确定