使用 Ansible 将标签添加到现有的 XML 命名空间

Add tag to existing XML namespace with Ansible

此处的目标是向 user-places.xbel 文件添加一个条目,该文件管理文件管理器的书签。

请参阅下面的预期输出(<bookmark:icon> 条目)以及 xbel 文件的整体文档结构。

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xbel>
<xbel xmlns:mime="http://www.freedesktop.org/standards/shared-mime-info" 
      xmlns:kdepriv="http://www.kde.org/kdepriv" 
      xmlns:bookmark="http://www.freedesktop.org/standards/desktop-bookmarks"
>
  <info>
    <!-- left out for simplicity -->
  </info>
  <bookmark href="ADDRESS">
    <title>My bookmark</title>
    <info>
      <metadata owner="http://freedesktop.org">
        <bookmark:icon name="network-workgroup"/>
      </metadata>
      <metadata owner="http://www.kde.org">
        <ID>123467890/0</ID>
        <OnlyInApp></OnlyInApp>
        <isSystemItem>false</isSystemItem>
        <isHidden>false</isHidden>
    </info>
  </bookmark>
</xbel>

我使用 Ansibles community.general.xml 来编辑这个文档。这是我的任务定义:

- name: Add file manager entry for NAS
  community.general.xml:
      path: .local/share/user-places.xbel.bak
      xpath: /xbel
      pretty_print: yes
      namespaces:
          bookmark: "http://www.freedesktop.org/standards/desktop-bookmarks"
      add_children:
          - bookmark:
              href: 'ADDRESS'
              _:
                  - title: My bookmark
                  - info:
                      _:
                          - metadata:
                              owner: 'http://freedesktop.org'
                              _:
                                  - "{bookmark}icon":
                                      name: 'network-workgroup'
                          - metadata:
                              owner: 'http://www.kde.org'
                              _:
                                  - ID: '1234567890/0'
                                  - OnlyInApp: ''
                                  - isSystemItem: 'false'
                                  - isHidden: 'false'

但是,这会生成此标记:

<ns0:icon xmlns:ns0="bookmark" name="network-workgroup"/>

而不是预期的标签:

<bookmark:icon name="network-workgroup"/>

我应该改变什么?

使用 LXML(Ansible 使用的 Python 库)添加命名空间时,建议您使用真实的命名空间而不是命名空间前缀:

The ElementTree API avoids namespace prefixes wherever possible and deploys the real namespace (the URI) instead

来源:https://lxml.de/tutorial.html#namespaces

因此,解决方法可能是在您的节点定义中完全做到这一点,并使用:

- "{http://www.freedesktop.org/standards/desktop-bookmarks}icon":

而不是

- "{bookmark}icon":

如果这样重复命名空间对您来说看起来很麻烦,您可以将它放入一个变量中并根据所述变量构建您的节点。
例如,在您的标签中添加那些 vars

boormark_ns: http://www.freedesktop.org/standards/desktop-bookmarks
icon_node: >-
  {{ 
    { 
      '{' ~ boormark_ns ~ '}icon': {
        'name': 'network-workgroup'
      } 
    } 
  }}

您的节点定义变为:

- "{{ icon_node }}"

所以,完整的任务是:

- name: Add file manager entry for NAS
  community.general.xml:
    path: tst.xml
    xpath: /xbel
    pretty_print: yes
    namespaces:
        bookmark: "{( boormark_ns )}"
    add_children:
        - bookmark:
            href: 'ADDRESS'
            _:
                - title: My bookmark
                - info:
                    _:
                        - metadata:
                            owner: 'http://freedesktop.org'
                            _:
                                - "{{ icon_node }}"
                        - metadata:
                            owner: 'http://www.kde.org'
                            _:
                                - ID: '1234567890/0aaaa'
                                - OnlyInApp: ''
                                - isSystemItem: 'false'
                                - isHidden: 'false'
  vars:
    boormark_ns: http://www.freedesktop.org/standards/desktop-bookmarks
    icon_node: >-
      {{ 
        { 
          '{' ~ boormark_ns ~ '}icon': {
            'name': 'network-workgroup'
          } 
        } 
      }}