使用 ElementTree 的 iterfind 进行深度 XML 解析
Using ElementTree's iterfind for deep XML parsing
我正在尝试使用 iterfind 解析所有 IPv6 address 元素。我认为我的匹配字符串是正确的,但我没有看到任何结果。我不熟悉解析深层 XML 文件,所以我开始质疑这种方法是最好的方法吗?
import requests
import xml.etree.ElementTree as ET
r = requests.get('https://support.content.office.net/en-us/static/O365IPAddresses.xml')
root = ET.fromstring(r.text)
for node in root.iterfind(".//products/product/[@name='o365']/addresslist/[@type='IPv6']"):
data = []
for d in node.getchildren():
if d.text:
data.append(d.text)
print ' '.join(data)
退后一步,确保您的 xpath 表达式是正确的。开始于:
>>> r = requests.get('https://support.content.office.net/en-us/static/O365IPAddresses.xml')
>>> root = ET.fromstring(r.text)
如果您搜索 xpath 表达式的开头,.//products
,您会得到什么?
>>> root.findall('.//products/product')
[]
你得到一个空列表,这意味着你的表达有问题。那是因为树的根是 products
元素:
>>> root
<Element 'products' at 0x7f16be5a9450>
因此层次结构的第一级将是 product
:
>>> root.findall('product')
[<Element 'product' at 0x7f16be5a9490>, <Element 'product' at 0x7f16be0e4190>, ...]
如果您将其替换回您的完整表达式,我们得到:
>>> root.findall("product/[@name='o365']/addresslist/[@type='IPv6']")
[<Element 'addresslist' at 0x7f16be5a94d0>]
看起来好多了。
在您的示例代码中使用该表达式会产生看似合理的输出。
我正在尝试使用 iterfind 解析所有 IPv6 address 元素。我认为我的匹配字符串是正确的,但我没有看到任何结果。我不熟悉解析深层 XML 文件,所以我开始质疑这种方法是最好的方法吗?
import requests
import xml.etree.ElementTree as ET
r = requests.get('https://support.content.office.net/en-us/static/O365IPAddresses.xml')
root = ET.fromstring(r.text)
for node in root.iterfind(".//products/product/[@name='o365']/addresslist/[@type='IPv6']"):
data = []
for d in node.getchildren():
if d.text:
data.append(d.text)
print ' '.join(data)
退后一步,确保您的 xpath 表达式是正确的。开始于:
>>> r = requests.get('https://support.content.office.net/en-us/static/O365IPAddresses.xml')
>>> root = ET.fromstring(r.text)
如果您搜索 xpath 表达式的开头,.//products
,您会得到什么?
>>> root.findall('.//products/product')
[]
你得到一个空列表,这意味着你的表达有问题。那是因为树的根是 products
元素:
>>> root
<Element 'products' at 0x7f16be5a9450>
因此层次结构的第一级将是 product
:
>>> root.findall('product')
[<Element 'product' at 0x7f16be5a9490>, <Element 'product' at 0x7f16be0e4190>, ...]
如果您将其替换回您的完整表达式,我们得到:
>>> root.findall("product/[@name='o365']/addresslist/[@type='IPv6']")
[<Element 'addresslist' at 0x7f16be5a94d0>]
看起来好多了。
在您的示例代码中使用该表达式会产生看似合理的输出。