假设我有这样的xml(真正的那个更复杂):
<a>
<b>
<c replace="alpha" />
</b>
<d>
<c replace="beta"></c>
</d>
</a>
我使用BeautifulSoup(lxml)解析了这个,因为我can't use regex。现在我用包含新的有效xml的字符串替换<c>
,该字符串取决于属性。这并不是那么难。
但是我想在不使用BeautifulSoup解析新的xml的情况下这样做。原因是我只是想在之后美化它。有相当多的标签被大量的xml取代。它不是非常高效的解析,然后美化一切。
是否有类似LiteralXmlPleaseDontParseThisTnx
节点的内容? (我找不到它,他们必须把它称为别的东西,并且'raw html','unparsed html','literal hmtl'......太多无关的点击。)。
或者,有没有办法对上面的xml进行美化处理,然后将新的xml作为纯文本插入(没有假设xml超出有效范围)?
答案 0 :(得分:2)
BeautifulSoup用于解析HTML。你所拥有的不是HTML,而是XML,所以你可能不应该使用BeautifulSoup,而是直接使用lxml。
lxml元素确实有replace
方法,但您必须传递一个元素,而不是字符串。我们不清楚你要用<c>
代替什么,但如果你从一开始就把你的替换值作为元素创建,你可以在不解析的情况下进行替换。
相反,如果您只是想删除一个任意字符串来代替<c>
,那么,这对XML文档来说不是一个格式良好的操作,而且库不可能可以保证你粘贴的内容是格式良好的,因此不可能将给定的结果序列化。大多数XML库都会特别禁止该操作,因为它会违反XML库试图维护的基本假设和保证。
答案 1 :(得分:0)
我找到了一种创建相同结果的方法,这对我来说很有用,但可能并不普遍适用。它位于&#39;或者&#39;问题类别:在解析汤之外做替换。
在解析主文档之前转义字符串格式化大括号:
escaped = sub(r'({|})', r'\1\1', input)
soup = BeautifulSoup(escaped, 'lxml') # or lxml
用替换字符串替换<c replace="alpha" />
(对于所有这些字符串):
name = c_tag.attrs['replace']
ctag.replace_with(NavigableString('{' + name + ':s}'))
将所有替换品存储在字典中(可能已经是这种情况):
rep = {'alpha': '<lots /><of-xml />', 'beta': '<b>hi</b>'}
使用字符串格式进行所有替换:
output = soup.prettify().format(**rep)
我承认我的案子有点特别,所以也许它对许多其他人没有帮助。但在我的情况下,每个<c>
可以被包含更多<c>
s的xml替换。由于多进程通信,每个级别都需要进行解析或pickle。 (酸洗比解析快20-50%,并且遇到硬递归限制)。所以必须只执行一次而不是每个级别,这节省了我很多时间(在我测试的情况下因子3),因为正则表达式替换和字符串替换比解析快得多。