总而言之,我是libxml的初学者,我必须使用现有的源代码。主要思想是应用第一个xpath表达式从xml文件中提取一组节点。然后,对于每个节点,应该应用第二个xpath表达式来提取一些值。
现有的源代码是:
int xt_parseXmlResult(xmlDocPtr doc, const char *xpath, assoc_arrayc_t expr, arrayc_t *result)
{
xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
// Register namespaces ...
/*
* Evaluate main xpath expression
*/
xmlXPathObjectPtr xpathNodes = xmlXPathEvalExpression((xmlChar *)xpath, xpathCtx);
/*
* Now we apply the xpath expressions on each node returned by the first xpath request
*/
// First loop is on the XML document as we have to create a new context each
// time we change the document
int nbDocs = xpathNodes->nodesetval->nodeNr;
for (row = 0; row < nbDocs; row++)
{
xmlXPathContextPtr subCtx = xmlXPathNewContext(doc);
// Register namespaces ...
// Update context to use the nodeset related to this row
subCtx->node = xpathNodes->nodesetval->nodeTab[row];
for (col = 0; col < expr.nbItems; col++)
{
// Evaluate expression
xpathRows = xmlXPathEvalExpression((xmlChar *)expr.itemList[col].val, subCtx);
result->data[(row + 1) * result->nbCols + col] = strdup((char *)xmlXPathCastToString(xpathRows));
xmlXPathFreeObject(xpathRows);
}
xmlXPathFreeContext(subCtx);
subCtx = NULL;
}
xmlFreeDoc(doc);
xmlXPathFreeContext(xpathCtx);
xmlXPathFreeObject(xpathNodes);
return 0;
}
我认为问题来自这一行
// Update context to use the nodeset related to this row
subCtx->node = xpathNodes->nodesetval->nodeTab[row];
因为第二个xpath表达式是从xml文件的根目录应用的,而不是每个节点的根目录。
关于如何做这件事的任何想法?
答案 0 :(得分:1)
你可以连接你的xpath表达式。
修改的
// FORECAST / DAY / descendant :: content / meteo / desc应该可以工作
答案 1 :(得分:1)
可能xmlXPtrNewContext应该有帮助,但我无法使用它。
我目前正在通过连接两个xpath并查询整个方法来实现这一目的。 新的xpath是:“(”+ xpath1 +“)”+“[num]”+ xpath2。 其中num可以替换为1和xpath1结果集的大小之间的任何数字。 它似乎有效。
答案 2 :(得分:0)
一些示例代码。修改以满足您的需求和语言。这是C#,但它应该大致相同。请注意,第二个xpath不是以“/”开头,而是使用从第一个返回的节点的实例。两条xpath都没有以“/".
结尾XmlDocument doc = new XmlDocument();
doc.Load(docfile);
XmlNodeList items = doc.SelectNodes("/part1/part2");
foreach (item in items)
{
XMLNode x = item.SelectNodes("part3");
//Dostuff
}