我遇到了一个问题,我正在使用beautifulsoup来解析从Tableau工作簿生成的xml,当我将结果写入文件时,它的行为不符合预期。选择bs4,它是标准的XML解析器,因为我发现它最容易让我的大脑理解,我不需要lxml解析器/包的速度。
背景:我的Tableau工作簿中有一个计算字段,该字段将在发布期间根据模板工作簿将转到的服务器和站点位置以编程方式更改。我已经完成并构建了一些函数,并编写了获取数据所需的所有内容,但是当我的脚本将xml写入文件时,它添加了一些与符号编码。这导致文件是有效的,可以在Tableau中打开,但该字段被认为是无效的,尽管看起来像有效的。我在想XML是如何在我的过程中的某个地方变得畸形的。
代码到目前为止,我认为问题发生的地方:
import bs4 as bs
twb = open(Script_config['local_file_location'], 'r')
bs_content = bs(twb, 'xml')
# formula_final below comes from another script that handles getting the data I need to programmatically generate the formula I need.
# Here is what I use to generate the bulk of the formula for Tableau
# 'When '[{}]' then {} '.format(rows['Column_Name'], rows['Formatted_ColumnName']))
# Does some other stuff and slaps together the formula I need as a string that can be written into my XML
# Verified that my result is coming over correctly and only changes once I do the replacement here and/or the writing of the file.
for calculation in bs_content.find_all('column', {'caption': 'Group By', 'datatype':'string', 'name':'[Calculation_12345678910]'}):
calculation.find('calculation')['formula'] = formula_final
with open('test.twb', 'w') as file:
file.write(str(bs_content))
示例XML:
<?xml version="1.0" encoding="utf-8"?>
<workbook source-build="2021.1.4 (20211.21.0712.0907)" source-platform="win" version="18.1" xml:base="https://localhost" xmlns:user="http://www.tableausoftware.com/xml/user">
...
<column caption="Group By" datatype="string" name="[Calculation_12345678910]" role="dimension" type="nominal">
<calculation class="tableau" formula="Case [Parameters].[Location External ID Parameter] When &apos;[Territory]&apos; then [Territory] End"/>
</column>
问题:在样例XML中,Tableau希望对XML进行格式化,而不将&
放在apos;
前面。应该是'
我试过的:想着我可以逃离&我把必要的斜杠放在适当的位置,以转义它在apos之前;部分,但是没有效果,我不知道如何使我的XML格式不总是将&号代码作为XML中其他特殊字符的一部分。
任何帮助将非常感激!
很好的问题描述。
您的问题被称为"双重转义"。您的程序正在读取已经被XML处理器序列化的数据。这就是为什么它包含'[{}]'
而不包含'[{}]'
我认为你的程序从文件中读取XML值作为一个简单的字符串,并将其分配给标记的值。但是当BeautifulSoup的XML处理器遇到&在标签值中,它必须用&
替换它。因此,您最终在XML输出中得到&apos;'
而不是'
。
快速而肮脏的解决方案是编写一些代码将所有XML实体替换为等效文本。一个更好的解决方案是使用XML解析器读取XML数据——这样,您的程序将自动接收预期的字符串值。