首页 文章

BeautifulSoup通过原始xml替换标记,无需解析/转义

提问于
浏览
1

说我有像这样的xml(真正的一个更复杂):

<a>
    <b>
        <c replace="alpha" />
    </b>
    <d>
        <c replace="beta"></c>
    </d>
</a>

我用BeautifulSoup(lxml)解析了这个,因为我can't use regex . 现在我用一个包含新的有效xml的字符串替换 <c> ,该字符串取决于属性 . 这并不是那么难 .

But 我想在没有使用BeautifulSoup解析新的xml的情况下这样做 . 原因是我不是非常高效的解析,然后美化一切 .

有什么像 LiteralXmlPleaseDontParseThisTnx 节点? (我可以't find it, they must have called it something else, and there are too many unrelated hits for ' raw html ', ' unparsed html ', ' literal hmtl'...) .

或者,有没有办法对上面的xml进行美化,然后将新的xml作为纯文本插入(没有假设xml超出有效范围)?

2 回答

  • 2

    BeautifulSoup用于解析HTML . 你拥有的不是HTML,而是XML,所以你可能不应该使用BeautifulSoup,而是直接使用lxml .

    lxml元素确实有一个replace方法,但是你必须传递一个Element,而不是一个字符串 . 它's unclear what you'试图用 <c> 替换,但是如果你从一开始就把你的替换值作为一个元素创建,你可以在不解析的情况下进行替换 .

    相反,如果您只是想删除一个任意字符串来代替 <c> ,那么,'s not a well-formed operation on an XML document, and there's无法保证您粘贴的内容格式正确,因此无法序列化给定的结果 . 大多数XML库都将特别禁止该操作,因为它会违反基础假设并保证XML库试图维护 .

  • 0

    我找到了一种方法来创建相同的结果,这对我来说很有用,但可能不适用 . 这是问题的“替代”类别:在解析的汤之外进行替换 .

    • 在解析主文档之前转义字符串格式化大括号:
    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> 的xml替换 . 由于多进程通信,每个级别都需要进行解析或pickle . (酸洗比解析快20-50%,并且遇到硬递归限制) . 因此,必须只执行一次而不是每个级别,这节省了我很多时间(在我测试的情况下因子3),因为正则表达式替换和字符串替换比解析快得多 .

相关问题