如何匹配字符串元素并更新plist中相应的响应字符串?
Posted
技术标签:
【中文标题】如何匹配字符串元素并更新plist中相应的响应字符串?【英文标题】:How to match a string element and updater the corresponding response string in a plist? 【发布时间】:2018-07-16 05:41:08 【问题描述】:我正在尝试如下更新 plist
匹配字符串字段“此提交中修复了哪些更改错误?”并更新<key>response</key>
对应的字符串字段
现在的问题代码更新字符串字段What change bugs are fixed in this submission?
,我如何更新相应的响应字符串字段?我也添加了预期的plist输出?有没有更简单的方法来做这个python?我哪里出错了?
代码:-
import re,os,fileinput
text1_to_search = re.compile(r'<string>What change bugs are fixed in this submission?.*</string>')
replacement1_text = """change://problem/219620> milestone: WCM-739#202 has failed to build in install: expected a type
change://problem/215275> Fix logic for PSK-->Open update
change://problem/1265279> Hotspot keeps changing from the device I selected
"""
for line in fileinput.input(filename, inplace=True, backup='.bak'):
print(text1_to_search.sub(replacement1_text, line)),
列表
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//company//DTD PLIST 1.0//EN" "http://www.company.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>28</key>
<dict>
<key>description</key>
<string>Which update of macOS, Xcode, and the SDKs was this submission built on with 'abc buildit'?</string>
<key>id</key>
<string>28</string>
<key>multiline</key>
<string>0</string>
<key>releases</key>
<array>
<string>milestone</string>
</array>
<key>response</key>
<string></string>
</dict>
<key>7</key>
<dict>
<key>description</key>
<string>What change bugs are fixed in this submission? (Please include the change number or URL followed by the title)</string>
<key>id</key>
<string>7</string>
<key>multiline</key>
<string>1</string>
<key>releases</key>
<array>
<string>milestone</string>
</array>
<key>response</key>
<string></string>
</dict>
</dict>
</plist>
更新后的预期输出
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//company//DTD PLIST 1.0//EN" "http://www.company.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>28</key>
<dict>
<key>description</key>
<string>Which update of macOS, Xcode, and the SDKs was this submission built on with 'abc buildit'?</string>
<key>id</key>
<string>28</string>
<key>multiline</key>
<string>0</string>
<key>releases</key>
<array>
<string>milestone</string>
</array>
<key>response</key>
<string></string>
</dict>
<key>7</key>
<dict>
<key>description</key>
<string>What change bugs are fixed in this submission? (Please include the change number or URL followed by the title)</string>
<key>id</key>
<string>7</string>
<key>multiline</key>
<string>1</string>
<key>releases</key>
<array>
<string>milestone</string>
</array>
<key>change://problem/219620> milestone: WCM-739#202 has failed to build in install: expected a type
change://problem/215275> Fix logic for PSK-->Open update
change://problem/1265279> Hotspot keeps changing from the device I selected</key>
<string></string>
</dict>
</dict>
</plist>
【问题讨论】:
【参考方案1】:Don't use regular expression to parse XML。使用 XML 解析器。在 Python 中,推荐使用lxml。
使用 XPath,这是一种可能的实现方式。
from lxml import etree as et
with open("input.xml") as raw:
# Parse the XML input file into a tree.
tree = et.parse(raw)
# Find the interesting <string> element by first finding the <string> to
# use as key, then the parent <dict>, then the <key> that preceeds the
# <string> to change. Since the xpath method returns a list, we take the
# first element of each list.
stringUsedAsKey = tree.xpath("/plist/dict/dict/string"
+ "[./text()=\"What change bugs are fixed in this submission? (Please include the change number or URL followed by the title)\"]")[0]
interestingDict = stringUsedAsKey.getparent()
stringToChange = interestingDict.xpath("key[text()=\"response\"]/following-sibling::string")[0]
# Change the text of the <string>.
stringToChange.text = "updated text"
# Write the changed tree back to an XML file.
tree.write("output.xml", pretty_print=True, xml_declaration=True, encoding="UTF-8")
【讨论】:
以上代码将 xml 中的任何地方的<string></string>
替换为 <string/>
,这是为什么以及如何修复它?
<string></string>
和 <string/>
是相同的,它们都是一个名为 string
的空元素。任何理智的 XML 解析都必须理解这两者。不过,可能有一种方法可以强制 lxml 不缩短空元素。
***.com/questions/34111154/… 似乎有帮助,使用了write_c14n
但顶部的xml声明不见了,你知道如何得到这个吗?
在我的回答中使用xml_declaration=True
。以上是关于如何匹配字符串元素并更新plist中相应的响应字符串?的主要内容,如果未能解决你的问题,请参考以下文章