2012-06-20 11 views
2

在nodejs中使用elementtree包,我試圖驗證xml文件中是否存在某個xml屬性(特別是一個android清單文件)。在屬性名稱中使用冒號搜索xpath表達式引發異常(node.js elementtree模塊)

var manifestTxt = fs.readFileSync('AndroidManifest.xml', 'utf-8'), 
    manifestDoc = new et.ElementTree(et.XML(manifestTxt)), 
    expected = 'application/activity[@android:name="com.whatever.app"]'; 

test.ok(manifestDoc.find(expected)); 

,我發現了以下異常:

node_modules/elementtree/lib/elementpath.js:210 
     throw new SyntaxError(token, 'Invalid attribute predicate'); 
     ^
Error: Invalid attribute predicate 

它似乎不喜歡在屬性名結腸,但沒有它的搜索不匹配。我想我正在處理命名空間錯誤 - 但找不到正確的方法。

編輯這裏的示例XML我在尋找:

<?xml version='1.0' encoding='utf-8'?> 
<manifest ... xmlns:android="http://schemas.android.com/apk/res/android"> 
    <application android:debuggable="true" android:icon="@drawable/icon" android:label="@string/app_name">&#xA; 
     <activity android:label="@string/app_name" android:name="com.whatever.app">&#xA;     
      <intent-filter>&#xA;</intent-filter> 
     </activity> 
    </application> 
    <uses-sdk android:minSdkVersion="5" /> 
</manifest> 
+0

你試過轉義冒號'\:'嗎? – mVChr

+0

是的,沒有效果。 – wildabeast

回答

2

ElementTree的預期空間URI,而不是命名空間前綴。

var manifestTxt = fs.readFileSync('AndroidManifest.xml', 'utf-8'), 
    manifestDoc = new et.ElementTree(et.XML(manifestTxt)), 
    expected = '//application/activity[@{http://schemas.android.com/apk/res/android}name="com.whatever.app"]'; 

test.ok(manifestDoc.find(expected)); 

參見:ElementTree: Working with Qualified Names


編輯node-elementtree的XPath實現不currently似乎並擁有命名空間的支持的。

缺少你必須做一些跑腿:

var manifestTxt = fs.readFileSync('AndroidManifest.xml', 'utf-8'), 
    manifestDoc = new et.ElementTree(et.XML(manifestTxt)), 
    activities = manifestDoc.findall('//application/activity'), i; 

for (i=0; i<activities.length; i++) { 
    if (activities[i].attrib['android:name'] === 'com.whatever.app') { 
    test.ok(true); 
    } 
} 

if (activities[i].attrib['android:name'] === 'com.whatever.app') {在很大程度上是一種猜測。

我不知道解析器如何處理名稱空間屬性。如有疑問,只需將整個activities[i].attrib轉儲到控制檯並查看解析器的功能。相應地調整上述代碼。我擔心這種XPath支持有限。

+0

謝謝,我曾嘗試過,雖然它不再拋出異常,但發現失敗(所以我認爲它也是錯誤的)。我已經添加了我正在搜索的示例xml。那麼問題就變成了,爲什麼發現失敗? – wildabeast

+0

這是一切,但XPath ... –

+0

@DimitreNovatchev沒錯。無論如何,這就是ElementTree按照文檔工作的原因(請參閱上面的「使用限定名稱」鏈接)。我不能做太多的事情。 – Tomalak

6

如果你沒有如何註冊名稱空間和使用相關的前綴,它的信息,使用

application/activity 
    [@*[local-name()=name' 
    and 
     namespace-uri() = 'http://schemas.android.com/apk/res/android' 
     ] 
    = 
    'com.whatever.app' 
    ] 

簡單表述,其並不在一般情況下的安全,

application/activity[@*[local-name()='name'] = 'com.whatever.app'] 

或該表達:而是可以在該特定情況下選擇想要的(多個)節點

application/activity[@*[name()='android:name'] = 'com.whatever.app'] 
相關問題