[英]Node selection using XPath in libxml2
我有一個類似於以下的XML文檔。
<library>
<artist name="a">
<album name="1"></album>
<album name="2"></album>
</artist>
<artist name="b">
<album name="8"></album>
<album name="9"></album>
</artist>
</library>`
我在Ubuntu上用Vala編寫應用程序,並使用libxml2庫來操作XML文檔。 我想獲取所有album
節點,而不管它們在文檔中的位置。 我編寫了以下代碼來完成上述工作。
document = Xml.Parser.parse_file (PATH_TO_DB);
...
Xml.XPath.Context context;
unowned Xml.XPath.Object *object;
context = new Xml.XPath.Context(document);
object = context.eval("//album");
if(object->nodesetval->is_empty())
return null;
return object->nodesetval->item(0);
...
此XPath查詢僅返回artist a
下的專輯,即專輯1和2.但是, context.eval("/library/artist[@name="b"]/album");
正在返回artist b
下的所有專輯。
上面顯示的代碼的python等價物產生了期望的結果。
doc = libxml2.parseFile("data.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//album")
Vala代碼有什么問題?
首先,您應該通過檢查object->type == Xml.ObjectType.NODESET
來檢查返回的對象是否為NodeSet。
接下來,您只返回結果節點集中的第一個項目。 有nodeset->length()
項。
void main() {
var document = Xml.Parser.parse_file ("file.xml");
run_query("//album", document);
run_query("/library/artist[@name=\"b\"]/album", document);
}
void run_query(string query, Xml.Doc* document) {
stdout.printf("Query: %s\n", query);
Xml.XPath.Context context;
unowned Xml.XPath.Object *object;
context = new Xml.XPath.Context(document);
object = context.eval(query);
assert(object->type == Xml.XPath.ObjectType.NODESET);
if(object->nodesetval->is_empty()) {
stdout.printf("empty");
return;
}
for (var i = 0; i < object->nodesetval->length(); i++) {
var node = object->nodesetval->item(i);
stdout.printf("node %s name=\"%s\"\n", node->name, node->get_prop("name"));
}
}
生產:
Query: //album
node album name="1"
node album name="2"
node album name="8"
node album name="9"
Query: /library/artist[@name="b"]/album
node album name="8"
node album name="9"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.