如何使用Python etree lxml xpath设置/替换xml中的值?
我想用Python2.7和etree/lxml/xpath解析一个AndroidManifest.xml,以查找属性名,并获取和设置它们的值 AndroidManifest.xml:如何使用Python etree lxml xpath设置/替换xml中的值?,xml,python-2.7,xpath,lxml,Xml,Python 2.7,Xpath,Lxml,我想用Python2.7和etree/lxml/xpath解析一个AndroidManifest.xml,以查找属性名,并获取和设置它们的值 AndroidManifest.xml: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.wearable.timer" >
<uses-sdk android:minSdkVersion="20"
android:targetSdkVersion="22" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault.Light"
android:allowBackup="true">
</application>
</manifest>
这就是我到目前为止所做的:
from lxml import etree
NS = {'android' : 'http://schemas.android.com/apk/res/android'}
tree = etree.parse('AndroidManifest.xml')
# get values
print tree.xpath("///@android:allowBackup", namespaces=NS)[0]
print tree.xpath("///@android:minSdkVersion", namespaces=NS)[0]
# set values ?
# write changes back to file ?
print etree.tostring(tree, encoding='utf-8', pretty_print=True)
这将打印true、20,然后打印整个未更改的xml文档
- 如何将allowBackup和minSdkVersion的值分别设置为false和19?
- 如果android:allowBackup或android:minSdkVersion尚未出现,如何添加它们
- 如何将更改写回文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable.timer">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="22"/>
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" android:allowBackup="false">
</application>
</manifest>
new.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable.timer">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="22"/>
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" android:allowBackup="false">
</application>
</manifest>
您现在知道如何编写更改,对于丢失的属性,它将按原样工作,如果值存在,我们将更新它,如果不存在,我们将创建它:
# no minSDk...
In [31]: !cat test.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.wearable.timer" >
<uses-sdk android:targetSdkVersion="22" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault.Light"
android:allowBackup="true">
</application>
</manifest>
In [32]: tree = et.parse("test.xml")
In [33]: root = tree.getroot()
In [34]: nsmap = root.nsmap
In [35]: android = nsmap["android"]
In [36]: tree.find("uses-sdk", nsmap).attrib[et.QName(android, "minSdkVersion")] = "17"
In [37]: tree.write("test.xml", encoding="utf-8")
# New attribute and value created.
In [38]: !cat test.xml<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable.timer">
<uses-sdk android:targetSdkVersion="22" android:minSdkVersion="17"/>
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" android:allowBackup="true">
</application>
</manifest>
In [39]:
#没有minSDk。。。
在[31]:!cat test.xml
在[32]中:tree=et.parse(“test.xml”)
在[33]中:root=tree.getroot()
在[34]中:nsmap=root.nsmap
在[35]:android=nsmap[“android”]
在[36]中:tree.find(“使用sdk”,nsmap).attrib[et.QName(android,“minSdkVersion”)]=“17”
[37]:tree.write(“test.xml”,encoding=“utf-8”)
#创建新属性和值。
在[38]:!cat test.xml
在[39]中:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable.timer">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="22"/>
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" android:allowBackup="false">
</application>
</manifest>
import lxml.etree as et
from StringIO import StringIO
tree = et.parse(StringIO(xml))
root = tree.getroot()
nsmap = root.nsmap
android = nsmap["android"]
tree.find("application", nsmap).attrib[et.QName(android, "allowBackup")] = "false"
tree.find("uses-sdk", nsmap).attrib[et.QName(android, "minSdkVersion")] = "17"
# write the updated html to "new.xml"
tree.write("new.xml", encoding="utf-8")
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable.timer">
<uses-sdk android:minSdkVersion="17" android:targetSdkVersion="22"/>
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" android:allowBackup="false">
</application>
</manifest>
# no minSDk...
In [31]: !cat test.xml<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.wearable.timer" >
<uses-sdk android:targetSdkVersion="22" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault.Light"
android:allowBackup="true">
</application>
</manifest>
In [32]: tree = et.parse("test.xml")
In [33]: root = tree.getroot()
In [34]: nsmap = root.nsmap
In [35]: android = nsmap["android"]
In [36]: tree.find("uses-sdk", nsmap).attrib[et.QName(android, "minSdkVersion")] = "17"
In [37]: tree.write("test.xml", encoding="utf-8")
# New attribute and value created.
In [38]: !cat test.xml<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wearable.timer">
<uses-sdk android:targetSdkVersion="22" android:minSdkVersion="17"/>
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.DeviceDefault.Light" android:allowBackup="true">
</application>
</manifest>
In [39]: