使用数字解析破碎的XML作为标记名称

问题描述 投票:1回答:2

我有很多xml文件,其密钥是数字格式,即<12345>Golly</12345>

使用ElementTree解析时,我得到一个错误not well-formed (invalid token)。我假设这是因为键是数字格式而不是单词。当我尝试通过使用正则表达式添加双引号来将键更改/替换为字符串

xmlstr = re.sub('<([\d]+)>','<"' + str(re.search('<([\d]+)>', xmlstr).group(1))+ '">',xmlstr)
xmlstr = re.sub('</([\d]+)>','</"' + str(re.search('</([\d]+)>', xmlstr).group(1))+ '">',xmlstr)

使用第一个找到的密钥替换所有其他密钥。(所有密钥最终都是相同的。而原始文件中的密钥本身在每个文档中都是唯一的。)我想这些文件直接从json转换为xml。键应表示id号,值是与id号关联的名称

我想知道是否有办法使用数字作为键,或者如果有一种方法我可以逐个替换键而不是用一个找到的字符串替换所有匹配。 .group(1)返回导致问题的第一个事件。请帮忙。

python regex xml string xml-parsing
2个回答
2
投票

我认为您需要同时拥有数字标记名称和在不同保存组中捕获的内容,然后在替换字符串中引用它们:

In [2]: data = "<content><12345>Golly</12345><67890>Jelly</67890></content>"

In [3]: re.sub(r"<(\d+)>(.*?)</\d+>", r'<item id="\1">\2</item>', data)
Out[3]: '<content><item id="12345">Golly</item><item id="67890">Jelly</item></content>'

但是,如果不能访问输入XML数据的可能变体,很难找到100%可靠的东西。例如,我不确定这个表达式是否能很好地处理嵌套数值标记。

您可能还想探索在lxml's "recovery" mode中解析文档的可能性。


可能有助于处理这种情况的另一个可能的工具是BeautifulSoup - 您可以尝试非传统方法 - 使用宽松的html5lib解析器解析XML数据:

In [1]: from bs4 import BeautifulSoup

In [2]: data = "<content><12345>Golly</12345><67890>Jelly</67890></content>"

In [3]: soup = BeautifulSoup(data, "html5lib")
In [3]: print(soup.prettify())
<html>
 <head>
 </head>
 <body>
  <content>
   &lt;12345&gt;Golly
   <!--12345-->
   &lt;67890&gt;Jelly
   <!--67890-->
  </content>
 </body>
</html>

当然,它不是理想的输出,但可能是你可以使用的东西,并提取键和单词。


0
投票

lxml包将使你的生活更容易与正则表达式斗争。

看看documentation page

pip install lxml

file_path = 'your/xml/file.xml'
parser_obj = lxml.etree.XMLParser(recover=True)
lxml.etree.parse(file_path, parser=parser_obj)
© www.soinside.com 2019 - 2024. All rights reserved.