【问题标题】:How to match a string element and updater the corresponding response string in a plist?如何匹配字符串元素并更新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>

【问题讨论】:

    标签: python 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 中的任何地方的 &lt;string&gt;&lt;/string&gt; 替换为 &lt;string/&gt;,这是为什么以及如何修复它?
    • &lt;string&gt;&lt;/string&gt;&lt;string/&gt; 是相同的,它们都是一个名为 string 的空元素。任何理智的 XML 解析都必须理解这两者。不过,可能有一种方法可以强制 lxml 不缩短空元素。
    • stackoverflow.com/questions/34111154/… 似乎有帮助,使用了write_c14n 但顶部的xml声明不见了,你知道如何得到这个吗?
    • 在我的回答中使用xml_declaration=True
    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    相关资源
    最近更新 更多