通过python xpath获取android清单元数据值

时间:2017-08-17 13:19:22

标签: python xpath

// from https://developer.android.com/reference/android/content/Context.html#BLUETOOTH_SERVICE    
// note that the actual string value is "bluetooth" not "BLUETOOTH_SERVICE", Context.BLUETOOTH_SERVICE is a constant that holds "bluetooth" string value
QAndroidJniObject service_name = QAndroidJniObject::fromString("bluetooth");     

// this is your context
QAndroidJniObject activity = QtAndroid::androidActivity(); 

// now you get your bluetooth manager
QAndroidJniObject bluetoothManager = activity.callObjectMethod("getSystemService","(Ljava/lang/String;)Ljava/lang/Object;", service_name.object<jstring>()); 

我想通过python

获取上面的daily_build_test

到目前为止,我试过了:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xiaomi.oga">
        ...
        <meta-data
            android:name="xxx"
            android:value="xxx" >
        </meta-data>

        <meta-data
            android:name="OTA_TYPE"
            android:value="daily_build_test" />


    </application>

</manifest>

我得到了:

import lxml.etree as ET
import os
ns='{http://schemas.android.com/apk/res/android}'
nametag=ns+'name'
categorytag='category'
packagetag='package'

class XmlParser:
    def __init__(self, file):
        self.file = file
        self.tree = None
        self.root = None

    def __parse(self):
        if self.tree is None or self.root is None:
            parser = ET.XMLParser(strip_cdata=False)
            self.tree = ET.parse(self.file, parser)
            self.root = self.tree.getroot()

    def gettree(self):
        self.__parse()
        return self.tree

    def getroot(self):
        self.__parse()
        return self.root

def get_meta_data(parser):
    tree = parser.gettree()
    #value = tree.xpath('/manifest/application//meta-data[@*=\'OTA_TYPE\']/@*[2]')
    NS = {'android' : 'http://schemas.android.com/apk/res/android'}
    value = tree.xpath('/manifest/application/meta-data[@a:name=\'OTA_TYPE\']/@a:value', namespace=NS)
    print '%s' %(value)
    return value

if __name__ == '__main__':
    file = os.environ['PYTHON_ARG']
    parser = XmlParser(file)
    meta_data = get_meta_data(parser)
    print '%s' %(meta_data)

或[&#39; daily_build_test&#39;] 当评论行:

Traceback (most recent call last):
  File "<stdin>", line 44, in <module>
  File "<stdin>", line 37, in get_meta_data
  File "src/lxml/lxml.etree.pyx", line 2272, in lxml.etree._ElementTree.xpath (src/lxml/lxml.etree.c:70786)
  File "src/lxml/xpath.pxi", line 352, in lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:179055)
  File "src/lxml/xpath.pxi", line 95, in lxml.etree._XPathContext.registerVariables (src/lxml/lxml.etree.c:175335)
  File "src/lxml/extensions.pxi", line 614, in lxml.etree._wrapXPathObject (src/lxml/lxml.etree.c:171074)
lxml.etree.XPathResultError: Unknown return type: dict

已应用

我不希望括号成为引号。

2 个答案:

答案 0 :(得分:2)

tree.xpath的论点是namespaces,而不是namespace。所以:

NS = {'a' : 'http://schemas.android.com/apk/res/android'}
value = tree.xpath('/manifest/application/'
                   'meta-data[@a:name=\'OTA_TYPE\']/@a:value',
                   namespaces=NS)

另请注意,您在android字典中使用了密钥NS,但在查询中使用了a:。上面的示例更正了字典,使其与您正在使用的前缀相匹配。

答案 1 :(得分:0)

Thanks to larsks, I finally get I want by:*


def get_meta_data(parser):
    tree = parser.gettree()
    NS = {'a' : 'http://schemas.android.com/apk/res/android'}
    value = tree.xpath('/manifest/application/meta-data[@a:name=\'OTA_TYPE\']/@a:value', namespaces=NS)
    print '%s' %(value[0]) 
    # NOTE value is a list of length 0.
    return value[0]