我有许多 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 情况:
- 标签/文本()
- 标签/@属性
- 姓名(DTBoolean/*[1])
- (标签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/