python 在嵌套的XML标签之间包含换行符(BeautifulSoup)

aydmsdu9  于 2023-06-20  发布在  Python
关注(0)|答案(2)|浏览(137)

我想测试一些(反)序列化代码是100%对称的,但我发现,当将数据序列化为嵌套的Tag时,内部的Tag之间没有像原始Tag那样的换行符。
有没有什么方法可以在嵌套的标签之间强制换行字符,而不需要prettify -> re-parse?
示例:

import bs4
from bs4 import BeautifulSoup

tag_string = "<OUTER>\n<INNER/>\n</OUTER>"
tag = BeautifulSoup(tag_string, "xml").find("OUTER")

print(tag)
... <OUTER>
... <INNER/>
... </OUTER>

new_tag = bs4.Tag(name="OUTER")
new_tag.append(bs4.Tag(name="INNER", can_be_empty_element=True))

tag == new_tag
... False

print(new_tag)
... <OUTER><INNER/></OUTER>

为了获得100%的对称序列化,我必须:

  • 将标记美化为字符串
  • 将“\n”替换为“\n”
  • 将此字符串解析为新的XML标记
  • 查找OUTER标签
new_tag = BeautifulSoup(
    new_tag.prettify().replace("\n ", "\n"), "xml"
).find("OUTER")

tag == new_tag
... True

print(new_tag)
... <OUTER>
... <INNER/>
... </OUTER>

该需求的依据:

  • 我正在使用一些特定于我的测试数据将数千个标记反序列化为对象
  • 当我开发这个特性时,我发现在几个属性的输入/输出之间有许多不匹配
  • 不匹配是不可接受的,因为它会导致读取此数据的闭源二进制文件执行应该避免的操作,除非该程序的数据库与此XML中的条目之间存在真正的差异
  • 我能够处理我的测试数据的这些不匹配,但是我不能保证这个代码的所有用户的序列化对称性
  • 因此,我认为最好是测试套件枚举用户数据的标签,Assert输入==输出,为了方便,我不得不做这种烦人的hackaround(prettify -> re-parse),如果可能的话,我希望避免这种情况
waxmsbnn

waxmsbnn1#

大多数序列化程序不给予这种级别的输出控制。
如果您正在寻找两个XML文档之间的“真正差异”,那么最好的解决方案是将两个文档都转换为规范形式。有一个XML规范化的标准和许多实现(Saxon序列化器中有一个选项,XOM库中有一个方法,当然还有其他方法)。

myss37ts

myss37ts2#

BeautifulSoup有一个NavigableString元素,它可以用来表示一个包含换行符的XML结构,而不必转换为字符串并解析回bs4.element.Tag
示例:

import bs4
from bs4 import BeautifulSoup

tag_string = "<OUTER>\n<INNER/>\n</OUTER>"
tag = BeautifulSoup(tag_string, "xml").find("OUTER")

new_tag = bs4.Tag(name="OUTER")
new_tag.append(bs4.NavigableString("\n"))
new_tag.append(bs4.Tag(name="INNER", can_be_empty_element=True))
new_tag.append(bs4.NavigableString("\n"))

tag == new_tag
... True

相关问题