Python正则表达式匹配:替换XML指定SHORT-NAME的INIT-VALUE内容
问题:如何替换指定XML节点内的INIT-VALUE部分?
原XML内容
<R-PORT-PROTOTYPE> <SHORT-NAME>VtDBGO_ReMotTqReqL2_null</SHORT-NAME> <REQUIRED-COM-SPECS> <NONQUEUED-RECEIVER-COM-SPEC> <DATA-ELEMENT-REF DEST="VARIABLE-DATA-PROTOTYPE">/FS_DBGO_pkg/FS_DBGO_if/VtDBGO_ReMotTqReqL2_null/VtDBGO_ReMotTqReqL2_null</DATA-ELEMENT-REF> <USES-END-TO-END-PROTECTION>false</USES-END-TO-END-PROTECTION> <ALIVE-TIMEOUT>0</ALIVE-TIMEOUT> <ENABLE-UPDATE>false</ENABLE-UPDATE> <FILTER> <DATA-FILTER-TYPE>ALWAYS</DATA-FILTER-TYPE> </FILTER> <HANDLE-NEVER-RECEIVED>false</HANDLE-NEVER-RECEIVED> <INIT-VALUE> <NUMERICAL-VALUE-SPECIFICATION> <VALUE>0</VALUE> </NUMERICAL-VALUE-SPECIFICATION> </INIT-VALUE> </NONQUEUED-RECEIVER-COM-SPEC> </REQUIRED-COM-SPECS> <REQUIRED-INTERFACE-TREF DEST="SENDER-RECEIVER-INTERFACE">/FS_DBGO_pkg/FS_DBGO_if/VtDBGO_ReMotTqReqL2_null</REQUIRED-INTERFACE-TREF> </R-PORT-PROTOTYPE>
替换需求
将其中SHORT-NAME为VtDBGO_ReMotTqReqL2_null的<R-PORT-PROTOTYPE>节点做以下修改:
- 添加
UUID="E8000CF6-DAFD-49C7-B1D4-D7EC20F43654"属性 - 将
SHORT-NAME修改为VtDBGO_FrMotTqReqL2_null - 替换节点内的
<INIT-VALUE>部分为以下结构:
<INIT-VALUE> <RECORD-VALUE-SPECIFICATION> <FIELDS> <NUMERICAL-VALUE-SPECIFICATION> <SHORT-LABEL>ElementConstant</SHORT-LABEL> <VALUE>0</VALUE> </NUMERICAL-VALUE-SPECIFICATION> <NUMERICAL-VALUE-SPECIFICATION> <SHORT-LABEL>ElementConstant_1</SHORT-LABEL> <VALUE>0</VALUE> </NUMERICAL-VALUE-SPECIFICATION> </FIELDS> </RECORD-VALUE-SPECIFICATION> </INIT-VALUE>
尝试过的无效正则方案
方案一
pattern_update=re.compile(r"""<R-PORT -PROTOTYPE> \s+<SHORT-NAME>{0}</SHORT-NAME> .*?<INIT-VALUE>((?:.(?!<REQUIRED-COM-SPECS>))*?)</INIT-VALUE>.*? \s+</R-PORT-PROTOTYPE>""".format(port),re.DOTALL | re.MULTILINE) _ar_xml_str = re.sub(pattern_update, replace_str, ar_xml_str) ar_xml_str = _ar_xml_str
方案二
pattern_update=re.compile(r"""<SHORT-NAME>VtDBGO_ReMotTqReqL2_null</SHORT-NAME> .*?<INIT-VALUE>(.*?)</INIT-VALUE>""",re.DOTALL | re.MULTILINE) _ar_xml_str = re.sub(pattern_update, replace_str, ar_xml_str) ar_xml_str = _ar_xml_str
正确实现方案
XML是结构化数据,用正则处理容易因嵌套标签、空格换行变化、属性存在等问题匹配失败,建议使用Python内置的xml.etree.ElementTree库来解析修改,代码如下:
import xml.etree.ElementTree as ET # 原XML内容(可替换为读取文件) original_xml = """ <R-PORT-PROTOTYPE> <SHORT-NAME>VtDBGO_ReMotTqReqL2_null</SHORT-NAME> <REQUIRED-COM-SPECS> <NONQUEUED-RECEIVER-COM-SPEC> <DATA-ELEMENT-REF DEST="VARIABLE-DATA-PROTOTYPE">/FS_DBGO_pkg/FS_DBGO_if/VtDBGO_ReMotTqReqL2_null/VtDBGO_ReMotTqReqL2_null</DATA-ELEMENT-REF> <USES-END-TO-END-PROTECTION>false</USES-END-TO-END-PROTECTION> <ALIVE-TIMEOUT>0</ALIVE-TIMEOUT> <ENABLE-UPDATE>false</ENABLE-UPDATE> <FILTER> <DATA-FILTER-TYPE>ALWAYS</DATA-FILTER-TYPE> </FILTER> <HANDLE-NEVER-RECEIVED>false</HANDLE-NEVER-RECEIVED> <INIT-VALUE> <NUMERICAL-VALUE-SPECIFICATION> <VALUE>0</VALUE> </NUMERICAL-VALUE-SPECIFICATION> </INIT-VALUE> </NONQUEUED-RECEIVER-COM-SPEC> </REQUIRED-COM-SPECS> <REQUIRED-INTERFACE-TREF DEST="SENDER-RECEIVER-INTERFACE">/FS_DBGO_pkg/FS_DBGO_if/VtDBGO_ReMotTqReqL2_null</REQUIRED-INTERFACE-TREF> </R-PORT-PROTOTYPE> """ # 目标INIT-VALUE内部结构 target_init_inner = """ <RECORD-VALUE-SPECIFICATION> <FIELDS> <NUMERICAL-VALUE-SPECIFICATION> <SHORT-LABEL>ElementConstant</SHORT-LABEL> <VALUE>0</VALUE> </NUMERICAL-VALUE-SPECIFICATION> <NUMERICAL-VALUE-SPECIFICATION> <SHORT-LABEL>ElementConstant_1</SHORT-LABEL> <VALUE>0</VALUE> </NUMERICAL-VALUE-SPECIFICATION> </FIELDS> </RECORD-VALUE-SPECIFICATION> """ # 解析XML root = ET.fromstring(original_xml) # 定位目标节点并修改 for port_node in root.findall(".//R-PORT-PROTOTYPE"): short_name = port_node.find("SHORT-NAME") if short_name and short_name.text == "VtDBGO_ReMotTqReqL2_null": # 添加UUID属性 port_node.set("UUID", "E8000CF6-DAFD-49C7-B1D4-D7EC20F43654") # 修改SHORT-NAME内容 short_name.text = "VtDBGO_FrMotTqReqL2_null" # 替换INIT-VALUE内容 init_value_node = port_node.find(".//INIT-VALUE") if init_value_node: # 清空原有子节点 for child in list(init_value_node): init_value_node.remove(child) # 添加目标结构 target_node = ET.fromstring(target_init_inner) init_value_node.append(target_node) # 输出修改后的XML modified_xml = ET.tostring(root, encoding="unicode", pretty_print=True) print(modified_xml)
方案说明
- 用XML解析库可以精准定位节点,不受空格、换行变化影响
- 直接操作节点对象,避免正则匹配时的嵌套标签、范围错误问题
- 可以灵活修改节点属性、文本内容,以及替换子节点
内容的提问来源于stack exchange,提问作者pipixia_626_
相关产品推荐
相关产品推荐

