使用名称空间的Python ElementTree find()

使用名称空间的Python ElementTree find(),python,xml,xpath,xml-namespaces,elementtree,Python,Xml,Xpath,Xml Namespaces,Elementtree,我试图使用Python的ElementTree来解析和修改xml文件。XML名称空间带来了混乱。我可以使用findall和finditer获取所有服务器的名称。但是,我无法使用xpath查询来查找特定的服务器。相反,find只是返回父元素 我需要做的是通过“name”或“machine”元素找到正确的服务器,并修改“arguments” <? xml version=’1.0’ encoding=’UTF-8’?> <domain xmlns=”http://xmlns.ora

我试图使用Python的ElementTree来解析和修改xml文件。XML名称空间带来了混乱。我可以使用findall和finditer获取所有服务器的名称。但是,我无法使用xpath查询来查找特定的服务器。相反,find只是返回父元素

我需要做的是通过“name”或“machine”元素找到正确的服务器,并修改“arguments”

<? xml version=’1.0’ encoding=’UTF-8’?>
<domain xmlns=”http://xmlns.oracle.com.weblogic/domain”>
  <server>
    <name>Server1-rma</name>
    <machine>server1</machine>
    <server-start>
      <arguments> -Xms4g</arguments>
    </server-start>
  </server>
  <server>
    <name>Server2-rma</name>
    <machine>server2</machine>
    <server-start>
      <arguments> -Xms4g</arguments>
    </server-start>
  </server>
  <server>
    <name>Server3-rma</name>
    <machine>server3</machine>
    <server-start>
      <arguments> -Xms4g</arguments>
    </server-start>
  </server>
</domain>
我希望能够匹配“machine”元素并拉取父元素,以便访问正确的“arguments”元素


我是xpath和elementtree的初学者,所以我肯定我只是做了一些不正确的事情。我只是不知道是什么。任何帮助都将不胜感激。

就像亚历杭德罗在评论中提到的一样。这对你要做的事情来说应该没什么大不了的。如果需要完整的XPath 1.0支持

然而,它也有一些其他的怪癖。其中之一是它会将自己的名称空间前缀添加到默认名称空间中。要保留默认名称空间,必须将其注册到

Alejandro还指出,选择服务器的正确XPath应该是:

/ns0:domain/ns0:server[ns0:machine='server2']
但是,当您构建树(使用
ET.parse()
)或获取根(使用
getroot()
)时,上下文已经是
ns0:domain
,因此该上下文中的XPath实际上是:

/ns0:server[ns0:machine='server2']
由于您希望更新服务器的
参数
,我们也可以将其添加到XPath中:

/ns0:server[ns0:machine='server2']/ns0:server start/ns0:arguments
有关XPath位置路径的详细信息

这里有一个完整的例子。(我使用前缀
wl
而不是
ns0
,只是为了表明前缀并不重要,只要它跟在前缀后面。)

XML输入(test.XML;固定了引号和XML声明)


服务器1 rma
服务器1
-Xms4g
服务器2 rma
服务器2
-Xms4g
服务器3 rma
服务器3
-Xms4g
Python

将xml.etree.ElementTree作为ET导入
tree=ET.parse(“test.xml”)
ns={“wl”:http://xmlns.oracle.com.weblogic/domain"}
ET.register_名称空间(“,ns[“wl”])
尝试:
tree.find(“./wl:server[wl:machine='server2']/wl:server start/wl:arguments”,名称空间=ns)。text=“BAM!!!”
除属性错误外:
打印(“找不到正确的服务器元素。”)
write(“output.xml”,xml\u声明=True,encoding=“UTF-8”)
XML输出(Output.XML)


服务器1 rma
服务器1
-Xms4g
服务器2 rma
服务器2
砰!!!
服务器3 rma
服务器3
-Xms4g

正确的XPath表达式是
/ns0:domain/ns0:server[ns0:machine='server2']
。谓词是同一位置步骤的一部分。另外,请注意
xml.etree
模块中的
ElementTree
感谢您的响应和信息。它可以工作!!!谢谢你的详细解释。这是一个有助于向前推进的问题。事实上,答案非常详细。
import xml.etree.ElementTree as ET
namespace = {‘ns0’: ‘ http://xmlns.oracle.com.weblogic/domain’}

tree = ET.parse(‘config.xml’)
root = tree.getroot()
for item in root.find((root + “ns0:server/[ns0:machine=’server2’]), namespace)
    print(item.tag)


output:
{http://xmlns.oracle.com.weblogic/domain}server