我必须使用DOM操作和XPath从iTunes Library XML文件中提取数据,格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Tracks</key>
<dict>
<dict>
<key>Track ID</key><integer>203</integer>
<key>Name</key><string>Winter</string>
<key>Artist</key><string>Daughter</string>
<!-- etc -->
<key>Play Count</key><integer>2</integer>
<key>Skip Count</key><integer>1</integer>
<key>Track Type</key><string>File</string>
</dict>
<dict>
Another set of track data, etc...
</dict>
</dict>
</dict>
</plist>
我需要能够从该文件中提取并存储数据位并将它们存储在数组中。 例如,我想将所有曲目名称存储在一个数组中,所有艺术家名称都存储在另一个数组中,但我不想存储其他值,例如播放/跳过计数。
我知道XPath的工作方式与此类似(如下面的switch语句所示),以便找到正确的位置,但键并不总是处于相同的位置。我正在有效地寻找一种基于前面值的值执行lookbehind断言的方法。
XPathExpression expr = xPath.compile("/plist/dict/dict/dict");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
StringBuilder outputString = new StringBuilder();
for (int i = 1; i <= nl.getLength(); i++) {
for (int j = 0; j < 6; j++) {
String label = "";
switch (j) {
case 0: expr = xPath.compile("/plist/dict/dict/dict["+i+"]/key[2]/text()");
//Append this value to TRACKNAME array with expr.evaluate
break;
case 1: expr = xPath.compile("/plist/dict/dict/dict["+i+"]/key[3]/text()");
//Append this value to ARTIST array with expr.evaluate
break;
case 2: /* ... */
}
}
}
答案 0 :(得分:1)
如果你的xml代码是正确的,你可以尝试这个解决方案:
/plist//dict["+i+"]/key[contains(text(),'Track ID')]/following-sibling::*[1]
它为关键元素创造了条件 - 如果包含文本(f.e。&#39; Track ID&#39;),找到第一个兄弟元素 - 在本例中为整数,其值为203.
在后续兄弟之后使用star可以捕获每个第一个没有兴趣的元素,如果它是整数或字符串元素。