2

总而言之,我完全是 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 文件的根目录应用的,而不是每个节点的根目录。

关于如何做这样的事情的任何想法?

4

3 回答 3

1

你可以连接你的 xpath 表达式。

编辑

//FORECAST/DAY/descendant::content/meteo/desc 应该可以工作

于 2009-01-29T17:32:56.353 回答
1

正如我在 xmlXPathContext::node 中看到的,它是供内部库使用的,所以我们不能使用它

xmlXPtrNewContext 可能会有所帮助,但我无法使用它。

我目前通过连接两个 xpath 并查询整体来做到这一点。新的 xpath 是:"(" + xpath1 + ")" + "[num]" + xpath2。其中 num 可以替换为 1 和 xpath1 结果集大小之间的任何数字。它似乎有效。

于 2012-02-07T11:01:25.610 回答
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
}
于 2009-01-29T19:03:16.467 回答