Ansible修改XML指定属性元素值时遭遇命名空间前缀未定义错误
解决Ansible XML模块的XPath命名空间前缀未定义错误
问题场景
需要批量修改XML文件中所有name属性为databaseName的resourceProperties元素的value属性值(例如将value="test.abc.com"替换为value="new_test.abc.com"),示例XML片段如下:
<?xml version="1.0" encoding= "UTF-8"?> <xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:resources.j2c="http://www.ibm.com/websphere/appserver/schemas/5.0/resources.j2c.xmi"> <resources.jdbc:JDBCProvider xmi:id="JDBCProvider_1" name="Oracle JDBC Driver (XA)" description="JDBC provider" providerType="Oracle JDBC Driver (XA)" isolatedClassloader="false" implementationClassName="oracle.jdbc.xa.client.OracleXADataSource" xa="false"> <classpath>${ORACLE_JDBC_DRIVER_PATH}/jdbc/Lib/gidbc7.jar</classpath> <classpath>$(ORACLE_JDBC_DRIVER_PATH}/jdbc/Lib/oidbc:.jar</classpath> <classpath>${ORACLE_JDBC_DRIVER_PATH}/rdbms/1L1b/xdb6.jar</classpath> <factories xmi:type="resources. jdbc: DataSource" xmi:id="DataSource_1" name="DWLConfig" JndiName="jdbc/DWLConfig" description="XA Datasource for"> <propertySet xmi:id="J2EEResourcePropertySet_1"> <resourceProperties xmi:id="J2EEResourceProperty_1" name="databaseName" type="java.lang.String" value="test.abc.com" required="true"/> <resourceProperties xmi:id="J2EEResourceProperty_2" name="driverType" type="java.Lang.String" value="4" description="" required="true"/> <resourceProperties xmi:id="J2EEResourceProperty_3" name="serverName" type="java.lang.String" value="test-scan.abc.com" required="true"/> <resourceProperties xmi:id="J2EEResourceProperty_4" name="portNumber" type="java.lang.String" value="1521" description="" required="true"/> <resourceProperties xmi:id="J2EEResourceProperty_5" name="webSphereDefaultIsolationLevel" type="java.lang.Integer" value="2"/> <resourceProperties xmi:id="J2EEResourceProperty_6" name= "downgradeHoldCursorsUnderXa" type="java.lang.Boolean" value="true"/> <resourceProperties xmi:id="J2EEResourceProperty_7" name="UseRRASetEquals" type="java.lang.Boolean" value="true" description="Set for pME"/> <resourceProperties xmi:id="J2EEResourceProperty_8" name="currentSchema" type="java.lang.String" value="INITIATE" description=""/> <resourceProperties xmi:id="J2EEResourceProperty_9" name="URL" type="java.lang.String"/> </propertySet> <connectionPool xmi:id="ConnectionPool_1" connectionTimeout="180" maxConnections="85" minConnections="I" reapTime="180" unusedTimeout="1800"/> <mapping xmi:id="MappingModule_1" mappingConfigAlias="" authDataAlias="Node01/User-config"/> </factories> </resources.jdbc:JDBCProvider> </xmi:XMI>
尝试使用以下Ansible Playbook执行修改:
- name: xml update xml: path: "{{ item }}" xpath: /xmi:XMI/resources.jdbc:JDBCProvider/factories/propertySet/resourceProperties[@name="database"] attribute: value value: new_test.abc.com state: present with_items: - file1.xml - file2.xml
执行后抛出错误:
XPathEvalError: Undefined namespace prefix
解决方案
问题原因
XPath中使用了xmi:和resources.jdbc:命名空间前缀,但Ansible的xml模块未被配置识别这些命名空间,必须显式声明对应映射;同时原XPath中的属性匹配值database与XML实际的databaseName不匹配。
修正后的Playbook
- name: xml update xml: path: "{{ item }}" xpath: /xmi:XMI/resources.jdbc:JDBCProvider/factories/propertySet/resourceProperties[@name="databaseName"] attribute: value value: new_test.abc.com state: present namespaces: xmi: http://www.omg.org/XMI resources.jdbc: http://www.ibm.com/websphere/appserver/schemas/5.0/resources.j2c.xmi with_items: - file1.xml - file2.xml
说明
namespaces参数定义了XML根节点中声明的两个命名空间,让Ansible能正确解析带前缀的XPath节点。- 修正了XPath中的属性匹配条件:将
@name="database"改为@name="databaseName",与XML片段中的元素属性保持一致。 - 执行该Playbook后,所有符合条件的
resourceProperties元素的value属性都会被替换为指定值。
内容的提问来源于stack exchange,提问作者reddy0969
相关产品推荐
相关产品推荐

