Python往事:ElementTree的单引号之谜

news2024/11/22 18:58:42

最近在针对某款设备的界面xml进行更新过程中,被告知回稿的字串放在了一个excel文件中,而我要上传到服务器的界面用语是用xml文件封装的。再经过详细求证了翻译组提供excel文件的原因后,我决定用python来完成界面用语xml的更新,但是在使用ElementTree库的时候,却发现这个库有点小瑕疵。就是会将xml文件的表头<xml/>这段中的双引号换成了单引号,虽然单双引号在解析xml上没有影响。但是如果上提交代码时有强校验的门禁处理等规则的话,就需要额外解释了。为此针对这个问题,查看了下源码并分享一种修改方案。

我遇到的情况如下图所示,原本要替换message的信息,结果执行完替换脚本后,发现xml声明表头也被替换了。这个变更在比较软件中会显得很明显。

发生这种事情的原因在于EelementTree#write()中将表头的格式默认写成了单引号。如下源码展示了write()的实现,可以发现在_get_wirte()的with循环体中直白的执行了一句写入操作:

<?xml version='1.0' encoding='%s'?>
    def write(self, file_or_filename,
              encoding=None,
              xml_declaration=None,
              default_namespace=None,
              method=None, *,
              short_empty_elements=True):
        """Write element tree to a file as XML.

        Arguments:
          *file_or_filename* -- file name or a file object opened for writing

          *encoding* -- the output encoding (default: US-ASCII)

          *xml_declaration* -- bool indicating if an XML declaration should be
                               added to the output. If None, an XML declaration
                               is added if encoding IS NOT either of:
                               US-ASCII, UTF-8, or Unicode

          *default_namespace* -- sets the default XML namespace (for "xmlns")

          *method* -- either "xml" (default), "html, "text", or "c14n"

          *short_empty_elements* -- controls the formatting of elements
                                    that contain no content. If True (default)
                                    they are emitted as a single self-closed
                                    tag, otherwise they are emitted as a pair
                                    of start/end tags

        """
        if not method:
            method = "xml"
        elif method not in _serialize:
            raise ValueError("unknown method %r" % method)
        if not encoding:
            if method == "c14n":
                encoding = "utf-8"
            else:
                encoding = "us-ascii"
        enc_lower = encoding.lower()
        with _get_writer(file_or_filename, enc_lower) as write:
            if method == "xml" and (xml_declaration or
                    (xml_declaration is None and
                     enc_lower not in ("utf-8", "us-ascii", "unicode"))):
                declared_encoding = encoding
                if enc_lower == "unicode":
                    # Retrieve the default encoding for the xml declaration
                    import locale
                    declared_encoding = locale.getpreferredencoding()
                write("<?xml version='1.0' encoding='%s'?>\n" % (
                    declared_encoding,))
            if method == "text":
                _serialize_text(write, self._root)
            else:
                qnames, namespaces = _namespaces(self._root, default_namespace)
                serialize = _serialize[method]
                serialize(write, self._root, qnames, namespaces,
                          short_empty_elements=short_empty_elements)

可能这是ElementTree在设计初为了方便在双引号中引用字串才将version和encoding改为用单引号展示。因为write()中没有复杂的间接依赖,可以直接将该方法复制到自己的工程里。为此,针对该处的修改就是重写ElementTree#write()。重新方案如下,先将源代码中的<?xml version='1.0' encoding='%s'?> 替换成 <?xml version=\"1.0\" encoding=\"%s\"?>。

同时针对提示引用缺失的方法,增加ElementTree前缀来指明调用路径。这样就可以保证整个write()也可以在自己的工程中被执行。修改后的代码如下:

def fix_write(self, file_or_filename,
              encoding=None,
              xml_declaration=None,
              default_namespace=None,
              method=None, *,
              short_empty_elements=True):
    if not method:
        method = "xml"
    elif method not in ElementTree._serialize:
        raise ValueError("unknown method %r" % method)
    if not encoding:
        if method == "c14n":
            encoding = "utf-8"
        else:
            encoding = "us-ascii"
    enc_lower = encoding.lower()
    with ElementTree._get_writer(file_or_filename, enc_lower) as write:
        if method == "xml" and (xml_declaration or
                                    (xml_declaration is None and
                                             enc_lower not in ("utf-8", "us-ascii", "unicode"))):
            declared_encoding = encoding
            if enc_lower == "unicode":
                # Retrieve the default encoding for the xml declaration
                import locale
                declared_encoding = locale.getpreferredencoding()
            write("<?xml version=\"1.0\" encoding=\"%s\"?>\n" % (
                declared_encoding,))
        if method == "text":
            ElementTree._serialize_text(write, self._root)
        else:
            qnames, namespaces = ElementTree._namespaces(self._root, default_namespace)
            serialize = ElementTree._serialize[method]
            serialize(write, self._root, qnames, namespaces,
                      short_empty_elements=short_empty_elements)

修改后,将原来调用ElementTree#write()的地方改成使用fix_write即可,同时不要忘了,将当前工程的elementTree对象作为第一入参穿进去。修改后的运行结果就会发现没有额外的格式变更了。

def update_fix():
    tree = ET.parse('element_test.xml')
    root = tree.getroot()
    messages = root.findall('message')
    messages[0].text = "no, it's so cold,let's take a shower"
    fix_write(tree, 'element_test_update_fix.xml', encoding="utf-8", xml_declaration=True)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1322034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5年开酸奶店的经历,告诉小白如何做市场调查

在开酸奶店之前&#xff0c;市场调查是必不可少的一步。 作为一个有 5 年开店经验的酸奶店老板&#xff0c;我将分享一些关于如何进行市场调查的实用建议。 1、确定目标市场 在开始市场调查之前&#xff0c;你需要先明确你的目标市场。你的酸奶店将面向哪些人群&#xff1f;…

如何通过ssh管道传输文件到ubuntu

如何在window系统中&#xff0c;通过ssh将指定的文件传输到ubuntu中呢&#xff1f; 比较常用的有以下种方式&#xff1a; 共享文件夹借助工具&#xff0c; FileZillaMobaxtermWinSCPXshell XFTP samba互传PuTTY pscp 今天主要分享一个使用python脚本搭建的一个&#xff0c;…

2023.12.17 关于 Redis 的特性和应用场景

目录 引言 Redis 特性 内存中存储数据 可编程性 可扩展性 持久化 支持集群 高可用性 Redis 优势 Redis 用作数据库 Redis 相较于 MySQL 优势 Redis 相较于 MySQL 劣势 Redis 用作缓存 典型场景 Redis 存储 session 信息 Redis 用作消息队列 初心 消息队列的…

谷歌手机安装证书到根目录

1、前提你已经root&#xff0c;安装好面具 2&#xff0c;下载movecert模块&#xff0c;自动帮你把证书从用户证书移动成系统证书 视频教程&#xff0c;手机为谷歌手机 https://www.bilibili.com/video/BV1pG4y1A7Cj?p11&vd_source9c0a32b00d6d59fecae05b4133f22f06 软件下…

众和策略:短线交易看什么?短线交易看什么指标?

短线交易看什么&#xff1f; 1、k线 当k线出现黄昏十字星、黑乌鸦、乌云盖顶等卖出形状图时&#xff0c;是一种卖出信号&#xff0c;当k线出现早晨十字星、红三兵、等买入形状图时&#xff0c;是一种买入信号。 2、均线 当均线出现死叉、空头摆放时是一种卖出信号&#xff…

商城免 费搭建之java鸿鹄云商 java电子商务商城 Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

【saas云平台】打造全行业全渠道全场景的saas产品&#xff0c;为经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营场景…

SpringIOC之ScopeMetadata

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

《服务器之间的图片传输 2023-12-19》模拟一台服务器(client)给另外一台服务(server)传输图片

Server public class PictureTestServer {public static void main(String[] args) {try (ServerSocket serverSocket new ServerSocket(0)) {System.out.println("服务器已启动&#xff0c;监听端口: " serverSocket.getLocalPort());Socket socket serverSocke…

Three.js中文网14入门案例

Three.js中文网 <template><div id"webgl"></div> </template><script setup> import * as THREE from three; import { OrbitControls } from three/addons/controls/OrbitControls.js;// 创建3D场景对象Scene const scene new TH…

ansible远程操作主机功能(1)

自动化运维&#xff08;playbook剧本yaml&#xff09; 是基于Python开发的配置管理和应用部署工具。自动化运维中&#xff0c;现在是异军突起。 Ansible能批量配置&#xff0c;部署&#xff0c;管理上千台主机&#xff0c;类似于Xshell的一键输入的工具&#xff0c;不需要每次…

playwright进阶问题,with sync_playwright() as p中的p是什么类型您知道吗?

playwritght中with as的用法 最近在看playwritght 的源码&#xff0c;大家都知道运行playwright的基础代码如下&#xff1a; with sync_playwright() as p:browser p.chromium.launch(channel"chrome", headlessFalse)page browser.new_page()page.goto("ht…

国产ToolLLM的课代表---OpenBMB机构(清华NLP)旗下ToolBench的安装部署与运行(附各种填坑说明)

ToolBench项目可以理解为一个能直接提供训练ToolLLM的平台&#xff0c;该平台同时构建了ToolLLM的一个开源训练指令集。&#xff0c;该项目是OpenBMB机构&#xff08;面壁智能与清华NLP联合成立&#xff09;旗下的一款产品&#xff0c;OpenBMB机构名下还同时拥有另外一款明星产…

JAVA编程题-交通工具信息查询系统

题目&#xff1a; 请编写一个交通工具信息查询系统&#xff0c;其中包含一个抽象父类&#xff1a;交通工具&#xff08;Transports&#xff09;类&#xff0c;四个具体子类飞机&#xff08;Plane&#xff09;类&#xff0c;轮船&#xff08;Ship&#xff09;类&#xff0c;火车…

结构体基础例题

这里写目录标题 例题一例题解析答案 例题二例题解析答案 例题三例题解析答案 例题四例题解析答案 例题五例题解析及答案 例题六例题解析及答案 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978…

手机数码品牌网站建设的作用是什么

手机数码产品几乎已经成为成年人必备的&#xff0c;包括手机、电脑、摄像机、键盘配件等&#xff0c;同时市场中相关企业也非常多&#xff0c;消费者可供选择的商品类型也很多样&#xff0c;而对企业来讲&#xff0c;只有不断提升品牌形象、获客拉新等才能不断提升企业地位&…

亚信安慧AntDB数据库成功助力通信业务核心转型

账务数据库扮演着通信运营商业务支撑系统的核心角色&#xff0c;负责处理亿万用户资料同步、充值缴费和账务记录等重要任务。在5G建设逐渐普及的趋势下&#xff0c;5G业务规模也逐步扩大。面对5G业务的新特点&#xff0c;账务系统对数据库的高并发和高可用性提出了更高的要求。…

Ubuntu系统使用Nginx搭建RTMP服务器

环境&#xff1a; 推流端 rockpi s 主控rk3308 运行ubuntu系统 服务端 ubuntu 播放器 VLC播放器 服务端安装依赖&#xff1a; apt-get install build-essential libpcre3 libpcre3-dev libssl-dev创建nginx编译目录&#xff1a; mkdir my_nginx_rtmp cd my_nginx_rtmp/下载 …

亚马逊,速卖通,shein卖家如何准确有效的测评补单

一、合理规划测评时间和数量 卖家需要合理规划测评的时间和数量。如果卖家过于频繁地进行测评&#xff0c;或者在短时间内进行大量的测评&#xff0c;这可能会被视为恶意行为&#xff0c;从而触犯风控机制。因此&#xff0c;卖家需要根据自己的销售情况和市场需求&#xff0c;…

【机器学习】卷积神经网络(CNN)的特征数计算

文章目录 基本步骤示例图解过程 基本步骤 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;计算最后的特征数通常涉及到以下步骤&#xff1a; 确定输入尺寸&#xff1a; 首先&#xff0c;你需要知道输入数据的尺寸。对于图像数据&#xff0c;这通常是 (batch_size, c…

ST股票预测模型(机器学习_人工智能)

知己知彼&#xff0c;百战不殆&#xff1b;不知彼而知己&#xff0c;一胜一负&#xff1b;不知彼&#xff0c;不知己&#xff0c;每战必贻。--《孙子兵法》谋攻篇 ST股票 ST股票是指因连续两年净利润为负而被暂停上市的股票&#xff0c;其风险较高&#xff0c;投资者需要谨慎…