python - 使用 lxml 解析奇怪结构的 XML

标签 python xml parsing lxml

我有许多 XML 文件需要解析。我写了一些有效但很丑陋的代码,我想从比我更有 XML 经验的人那里得到一些建议。

首先,我可能在错误的上下文中使用了一些术语,因为我在 XML 方面的经验有限。对于元素,除非另有说明,我的意思是这样的:

 <root>
  <element>
   ...
  </element>
  <element>
   ...
  </element>
 </root>  

无论如何,每个文件都包含许多元素,以及许多子元素(很明显)。令我感到困惑的是,需要以四种不同的方式访问相关值;

1)节点文本:

<tag>value</tag>

2)属性:

<tag attribute="value"></tag>

3) 标签内“隐藏”的值(本例中为“true”):

<tag><boolean.true/></tag>

4) 同名标​​签(“tagA”)内的值,但具有不同名称(“tag1”和“tag2”)的“祖 parent ”标签,都在同一元素内。 “tagA”对我没有用,我会寻找“tag1”和“tag2”。

<element>
   <tag1><tagA>value</tagA><tag1>
   <tag2><tagA>value</tagA></tag2>
</element>

目前我有一本字典,每个文件都是一个键。这些值是具有键“属性”、“节点文本”、“标签”和“父元素”的字典。

例子:

{'file1.xml' : 'attributes' : {'Person': 'Id', 'Car' : 'Color'},
               'node text': ['Name', 'Address'],
}

其中“Person”和“Car”是标签,“Id”和“Color”是属性名。

这使得迭代所有元素并检查每个标签变得容易,如果字典中有匹配项(如果 elem.tag in dict['file1.xml']['attributes']),提取值.

正如我所说,代码有效,但我不喜欢我的解决方案。此外,并非所有元素都具有所有子元素(例如,一个人可能没有汽车,那么该标签将完全丢失),我需要为这些值分配“无”。现在我得到了每个文件中每个元素应该存在的所有标签,将它们变成一个集合,然后检查这些标签与我实际从该元素中提取值的标签集之间的差异。同样,代码非常难看。

希望这个烂摊子是有道理的。

编辑:

我采纳了 J.F. Sebastian 的建议,将每个值的 xpath 存储在字典中,字段名称作为键,xpath 作为值。

最佳答案

您可以通过使用与您的元素相关的 xpath 表达式而不是复杂的数据结构来简化您的输入 代码,例如,#1-4 情况:

  1. 标签/文本()
  2. 标签/@属性
  3. 姓名(DTBoolean/*[1])
  4. (标签1|标签2)/*/文本()

使用什么输出数据结构取决于您希望以后如何在您的代码中使用它。您可以从最适合您当前代码的结构开始。并在您更好地理解需求后将其发展为更通用的解决方案。

I output it to csv, where each element is one row in the csv file. ... I use a defaultdict to store the elements and then store those in a list before I output them to csv.

你可以使用普通的字典和 csv.DictWriter(fieldnames=xpathdict.keys()):

# for each element
row_dict = dict.fromkeys(xpathdict.keys())
...
# for each key 
row_dict[key] = element.xpath(xpathdict[key]) or None
...
dictwriter.writerow(row_dict)

其中xpathdict是字段名和对应的xpath表达式之间的映射。一般而言,您可以存储函数对象 f(element) -> csv field 来代替/除 xpath exprs 之外。

关于python - 使用 lxml 解析奇怪结构的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7894357/

相关文章:

如果放在模块中,Python 无法导入名称

python - 通过序列化器创建多模型实例怎么样?

python - gammu.ERR_TIMEOUT - 树莓派

java - 在 android studio 项目中显示文本

JavaCC:请给我 "real"示例的链接

c++ - 在 C++ 中解析字符串

java - 如何将日期解析为 EEE MMM dd HH :mm:ss zzz yyyy format?

python - 如何从 C++ 启动 Python 线程?

ios - 如何在 xcode 7 中添加 libxml2.dylib

xml - 如何通过 XSD 允许 XML 元素出现在任何地方?