我想测试一些(反)序列化代码是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),如果可能的话,我希望避免这种情况
2条答案
按热度按时间waxmsbnn1#
大多数序列化程序不给予这种级别的输出控制。
如果您正在寻找两个XML文档之间的“真正差异”,那么最好的解决方案是将两个文档都转换为规范形式。有一个XML规范化的标准和许多实现(Saxon序列化器中有一个选项,XOM库中有一个方法,当然还有其他方法)。
myss37ts2#
BeautifulSoup有一个NavigableString元素,它可以用来表示一个包含换行符的XML结构,而不必转换为字符串并解析回
bs4.element.Tag
。示例: