python - 使用 Ansible 解析带有命名空间的 XML,特别是 JBOSS standalone.xml

标签 python xpath ansible

我正在尝试更改 JBoss 服务器的 standalone-full.xml 配置文件中的值。我遇到的问题是 namespace 。我已经进行了几次搜索并尝试了几种不同的场景,我将提供这些场景。我知道这与命名空间有关,因为当我删除它时,剧本就可以工作了。我的猜测是我遗漏了一些简单的东西,如果能提供任何帮助,我将不胜感激。我不太了解 xpath,这可能是问题的很大一部分。

下面是示例代码,以及实现此功能的不同尝试。

示例.xml:

<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:1.7">
<extensions>
    <!-- <extension module="org.jboss.as.clustering.infinispan"/>-->
    <extension module="org.jboss.as.cmp"/>
    <extension module="org.jboss.as.connector"/>
    <extension module="org.jboss.as.deployment-scanner"/>
    <extension module="org.jboss.as.ee"/>
    <extension module="org.jboss.as.ejb3"/>
    <extension module="org.jboss.as.jacorb"/>
    <extension module="org.jboss.as.jaxr"/>
    <extension module="org.jboss.as.jaxrs"/>
    <extension module="org.jboss.as.jdr"/>
    <extension module="org.jboss.as.jmx"/>
    <extension module="org.jboss.as.jpa"/>
    <extension module="org.jboss.as.jsf"/>
    <extension module="org.jboss.as.jsr77"/>
    <extension module="org.jboss.as.logging"/>
    <extension module="org.jboss.as.mail"/>
    <extension module="org.jboss.as.messaging"/>
    <extension module="org.jboss.as.naming"/>
    <extension module="org.jboss.as.pojo"/>
    <extension module="org.jboss.as.remoting"/>
    <extension module="org.jboss.as.sar"/>
    <extension module="org.jboss.as.security"/>
    <extension module="org.jboss.as.threads"/>
    <extension module="org.jboss.as.transactions"/>
    <extension module="org.jboss.as.web"/>
    <extension module="org.jboss.as.webservices"/>
    <extension module="org.jboss.as.weld"/>
</extensions>
<system-properties>
    <property name="app.datasource.connection-url" value="jdbc:oracle:thin:@(description=(address=(protocol=tcp)(host=mdatabase.example.com)(port=1521))(connect_data=(service_name=myservice)))"/>
    <property name="app.datasource.security.user-name" value="Myuser"/>
    <property name="app.datasource.security.password" value="mypassword"/>
</system-properties>
</server>

simpleplay.xml:

---
- hosts: all
  gather_facts: no
  connection: local
  tasks:
    - name: "Read XML"
      xml:
        path: sample.xml
        xpath: /server/system-properties/property[@name='app.datasource.security.user-name']
        attribute: value
        content: attribute
     register: my_val


- name: "Show me"
  debug:
    var: my_val

无主机:

localhost
  1. 第一次尝试:(向我证实命名空间是我的问题。) 在我更改的 sample.xml 中:

    <server xmlns="urn:jboss:domain:1.7">
    

    <server>
    

生产:

    PLAY [all] *******************************************************************************************************************************************************************************************************

    TASK [Read XML] **************************************************************************************************************************************************************************************************
    ok: [localhost]

    TASK [Show me] ***************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "my_val": {
        "actions": {
            "namespaces": {},
            "state": "present",
            "xpath": "/server/system-properties/property[@name='app.datasource.security.user-name']"
        },
        "changed": false,
        "count": 1,
        "failed": false,
        "matches": [
            {
                "property": {
                    "name": "app.datasource.security.user-name",
                    "value": "Myuser"
                }
            } 
        ],
        "msg": 1
        }
    }

    PLAY RECAP *******************************************************************************************************************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0
  1. 将命名空间添加到 xml 中,并将命名空间添加回 sample.xml:

    ---
    - hosts: all
      gather_facts: no
      connection: local
      tasks:
        - name: "Read XML"
          xml:
            path: sample.xml
            xpath: /x:server/system-properties/property[@name='app.datasource.security.user-name']
            namespaces:
              x: "urn:jboss:domain:1.7"
            attribute: value
            content: attribute
         register: my_val
    

    产生:

    PLAY [all] *******************************************************************************************************************************************************************************************************
    
    TASK [Read XML] **************************************************************************************************************************************************************************************************
    fatal: [localhost]: FAILED! => {"changed": false, "msg": "Xpath /x:server/system-properties/property[@name='app.datasource.security.user-name'] does not reference a node!"}
    to retry, use: --limit @/home/ec2-user/work/xpathtest/simpleplay.retry
    
    PLAY RECAP *******************************************************************************************************************************************************************************************************
    localhost                  : ok=0    changed=0    unreachable=0    failed=1
    

我尝试过的几种xpaths:

  • /x:server/x:system-properties/x:property[@x:name='app.datasource.security.user-name']

  • /server[namespace-uri()='urn:jboss:domain:1.7']/system-properties/property[@name='app.datasource.security.user-name']

  • /*[local-name()=server]/system-properties/property[@name='app.datasource.security.user-name']

也都产生了上述结果。

我担心的是我对命名空间的理解不够透彻,看不出我做错了什么。任何帮助将不胜感激。

最佳答案

问题在于命名空间。所有元素都绑定(bind)到命名空间 urn:jboss:domain:1.7。有点难看,因为没有命名空间前缀。所有元素都绑定(bind)到该 namespace ,但除非 namespace 前缀用于属性,否则不会。

因此,您的 XPath: /x:server/x:system-properties/x:property[@x:name='app.datasource.security.user-name'] 应该是:

/x:server/x:system-properties/x:property[@name='app.datasource.security.user-name']

对于 XPath:/server[namespace-uri()='urn:jboss:domain:1.7']/system-properties/property[@name='app.datasource.security.user-name' ] 你需要在任何元素 * 上进行一般匹配,然后使用谓词通过 local-name() 进行限制,也可以使用 namespace-uri() 作为标准:

/*[local-name() = 'server' and namespace-uri() = 'urn:jboss:domain:1.7']/*[local-name() = 'system-properties']/*[local-name() = 'property' and @name='app.datasource.security.user-name']

对于 XPath /*[local-name()=server]/system-properties/property[@name='app.datasource.security.user-name'],你没有有 server 引号。它试图将 local-name() 与不存在的子元素 server 进行比较。同样,您需要使用谓词来匹配后代的 local-name():

/*[local-name()='server']/*[local-name() = 'system-properties']/*[local-name() = 'property' and @name='app.datasource.security.user-name']

关于python - 使用 Ansible 解析带有命名空间的 XML,特别是 JBOSS standalone.xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54677907/

相关文章:

ansible - 在 Ansible play 中覆盖 IP 地址或主机标签

python - 简单的 TensorFlow 神经网络最小化成本函数,但所有结果都接近 1

python - 为什么将 Python 系统类与自定义类合并不如 Hook 导入机制可取?

xml - 如何选择除特定元素之外的特定元素的所有兄弟元素

java - 如何使用 selenium webdriver-Java 验证页面中显示的错误消息

ansible - 如何在ansible中处理未经验证的apt安装

python - 如何使用 mw 字典添加新字符串列表的分子量?

python - 内部指针方法的工作原理

ruby-on-rails-3 - xPath 最后一个选择元素

ansible:在模板字符串中检测到递归循环