Home > Back-end >  Add tag to existing XML namespace with Ansible
Add tag to existing XML namespace with Ansible

Time:04-29

The goal here is to add an entry to the user-places.xbel file which manages bookmarks for file managers.

See below both the expected output (the <bookmark:icon> entry), as well as the overall document structure of the xbel file.

<?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>

I use Ansibles community.general.xml to edit this document. This is my task definition:

- 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'

However, this generates this tag:

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

instead of the expected tag:

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

What should I change?

CodePudding user response:

When adding a namespace with LXML (the Python library used by Ansible) it is recommended that you use the real namespace and not the namespace prefix:

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

Source: https://lxml.de/tutorial.html#namespaces

So, a fix could be to do exactly that in your node definition, and use:

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

instead of

- "{bookmark}icon":

If that looks cumbersome to you to repeat the namespace like that, you could fit it in a variable and construct your node based on the said variable.
For example, adding those vars in your tag:

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

Your node definition become:

- "{{ icon_node }}"

And so, the full task is:

- 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'
          } 
        } 
      }}
  • Related