在“header”中声明xml文件的命名空间使用 python ElementTree

发布于 2025-01-12 03:39:13 字数 2536 浏览 1 评论 0原文

我有一个函数,它接受多个输入并为我生成一些 xml 元素,为此我需要几个已定义的不同名称空间。问题是,当我生成文件时,它总是会在我用来指定应生成元素的位置的标签中声明名称空间。我希望声明发生在第一个元素中,在我的例子中是“svg”元素。这是代码:

if not self.hasSelfHeader and not self.hasDefsHeader:
        self.outputRoot.insert(0, ET.Element(ET.QName(self.someNamespace, 'self')))
        self.selfHeader = self.outputRoot[0]
        self.outputRoot.insert(1, ET.Element('defs'))
        self.defsHeader = self.outputRoot[1]
        
    newParamDef = ET.SubElement(self.selfHeader, ET.QName(self.someNamespace, 'paramDef'))
    newParamDef.set('name', name)
    newParamDef.set('type', type)
    newParamDef.set('default', value)
            
    newLocalDef = ET.SubElement(self.defsHeader, ET.QName(self.someNamespace, 'localDef'))
    newLocalDef.set('name', 'local_' + name)
    newLocalDef.set('type', type)
    newLocalDef.set(ET.QName(self.someotherNamespace, 'value'), name)

    tree = ET.ElementTree(self.outputRoot)
    tree.write("testing.xml" , encoding='utf-8', xml_declaration=False)

我给程序的输入是:

<svg viewBox="0 0 120 120" version="1.1"
  xmlns="http://www.w3.org/2000/svg">
  <circle id="one" cx="60" cy="60" r="50"/>
  <rect id="two" x="0" y="0" width="10" height="20"/>
</svg>

我想要得到的输出:

    <svg xmlns="http://www.w3.org/2000/svg"
    xmlns:ns="http:namespace.com"
    xmlns:nsbind="http:namespace.com/bind/"
     viewBox="0 0 120 120" version="1.1">
          <ns:self>
            <hmi:paramDef name="test" type="Color" default="0xFFEEEEEE"/>
          </ns:self>
          <defs>
            <ns:localDef name="local_test" type="Color" nsbind:value="{{ParamProps.test}}"/>
          </defs>
<circle id="one" cx="60" cy="60" r="50"/>
      <rect id="two" x="0" y="0" width="10" height="20"/>
    </svg>

生成的输出:

      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" version="1.1">
      <ns:self xmlns:ns="http:namespace.com">
        <hmi:paramDef name="test" type="Color" default="0xFFEEEEEE"/>
      </ns:self>
      <defs>
        <ns:localDef xmlns:ns="http:namespace.com"  name="local_test" type="Color" nsbind:value="{{ParamProps.test}}"/>
      </defs>
<circle id="one" cx="60" cy="60" r="50"/>
      <rect id="two" x="0" y="0" width="10" height="20"/>
    </svg>

我明白为什么它不起作用,它无法访问 xml 文件的“头”,因此将放置它可以找到的最顶层元素的命名空间声明,但我只是不知道如何以不同的方式进行操作。

I have a function which takes a number of inputs and generates some xml elements for me and for that I need a couple of different namespaces which I have defined. Problem is, when I generate the file it will always declare the namespaces in the tag I used to specify the location of where the elements should be generated. I want the declarations to happen in the first element, in my case the 'svg' element. Here is the code:

if not self.hasSelfHeader and not self.hasDefsHeader:
        self.outputRoot.insert(0, ET.Element(ET.QName(self.someNamespace, 'self')))
        self.selfHeader = self.outputRoot[0]
        self.outputRoot.insert(1, ET.Element('defs'))
        self.defsHeader = self.outputRoot[1]
        
    newParamDef = ET.SubElement(self.selfHeader, ET.QName(self.someNamespace, 'paramDef'))
    newParamDef.set('name', name)
    newParamDef.set('type', type)
    newParamDef.set('default', value)
            
    newLocalDef = ET.SubElement(self.defsHeader, ET.QName(self.someNamespace, 'localDef'))
    newLocalDef.set('name', 'local_' + name)
    newLocalDef.set('type', type)
    newLocalDef.set(ET.QName(self.someotherNamespace, 'value'), name)

    tree = ET.ElementTree(self.outputRoot)
    tree.write("testing.xml" , encoding='utf-8', xml_declaration=False)

The input I give into my program is:

<svg viewBox="0 0 120 120" version="1.1"
  xmlns="http://www.w3.org/2000/svg">
  <circle id="one" cx="60" cy="60" r="50"/>
  <rect id="two" x="0" y="0" width="10" height="20"/>
</svg>

The output I want to get:

    <svg xmlns="http://www.w3.org/2000/svg"
    xmlns:ns="http:namespace.com"
    xmlns:nsbind="http:namespace.com/bind/"
     viewBox="0 0 120 120" version="1.1">
          <ns:self>
            <hmi:paramDef name="test" type="Color" default="0xFFEEEEEE"/>
          </ns:self>
          <defs>
            <ns:localDef name="local_test" type="Color" nsbind:value="{{ParamProps.test}}"/>
          </defs>
<circle id="one" cx="60" cy="60" r="50"/>
      <rect id="two" x="0" y="0" width="10" height="20"/>
    </svg>

And the generated output:

      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" version="1.1">
      <ns:self xmlns:ns="http:namespace.com">
        <hmi:paramDef name="test" type="Color" default="0xFFEEEEEE"/>
      </ns:self>
      <defs>
        <ns:localDef xmlns:ns="http:namespace.com"  name="local_test" type="Color" nsbind:value="{{ParamProps.test}}"/>
      </defs>
<circle id="one" cx="60" cy="60" r="50"/>
      <rect id="two" x="0" y="0" width="10" height="20"/>
    </svg>

I get why it doesn't work, it cannot access the 'head' of the xml file and will therefore place the namespace declarations at the most top-level element it can find, but I just don't know how to do it differently.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文