簡體   English   中英

在 c 程序中使用帶有 libxml2 庫的 osm 文件中使用 xpath 的問題

[英]Problem with using xpath in on osm file with libxml2 library in c programe

我正在使用 libxml2 和 C 語言處理 XML 文件(特別是.osm 文件)。

這是我的 XML 源(不是全部,只是一塊):

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="CGImap 0.3.3 (17077 thorn-02.openstreetmap.org)" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
 <bounds minlat="48.8416800" minlon="2.3422900" maxlat="48.8430200" maxlon="2.3456400"/>
 <node id="470136" visible="true" version="7" changeset="4816046" timestamp="2010-05-26T19:25:12Z" user="Mawie" uid="150619" lat="48.8443318" lon="2.3420496">
  <tag k="highway" v="traffic_signals"/>
 </node>
 <node id="25033471" visible="true" version="2" changeset="4486432" timestamp="2010-04-21T13:24:55Z" user="Mawie" uid="150619" lat="48.8426543" lon="2.3443756"/>
 <node id="25033470" visible="true" version="3" changeset="4486432" timestamp="2010-04-21T13:24:55Z" user="Mawie" uid="150619" lat="48.8424525" lon="2.3442707"/>
 <node id="25033533" visible="true" version="4" changeset="4063350" timestamp="2010-03-07T17:01:22Z" user="lapinos03" uid="33634" lat="48.8427422" lon="2.3413616"/>
 <node id="1110453124" visible="true" version="3" changeset="19056700" timestamp="2013-11-22T15:46:42Z" user="Élie Gouzien" uid="1811864" lat="48.8419798" lon="2.3444183">
  <tag k="name" v="Aquarium"/>
 </node>
 <node id="1750369420" visible="true" version="2" changeset="19056700" timestamp="2013-11-22T15:46:42Z" user="Élie Gouzien" uid="1811864" lat="48.8422145" lon="2.3455341">
  <tag k="amenity" v="theatre"/>
  <tag k="name" v="Nouveau théâtre"/>
 </node>
.
.
.
<way id="4217107" visible="true" version="5" changeset="4768013" timestamp="2010-05-21T17:45:57Z" user="Esperanza36" uid="83557">
  <nd ref="25033470"/>
  <nd ref="25033531"/>
  <tag k="cycleway" v="opposite"/>
  <tag k="highway" v="residential"/>
  <tag k="maxspeed" v="30"/>
  <tag k="name" v="Rue Louis Thuillier"/>
  <tag k="oneway" v="yes"/>
 </way>
.
.
.
</osm>

...

我正在嘗試使用 xpath 表達式檢索節點“方式”,我想要獲取的特定方式節點是具有屬性標簽 k =“高速公路”的節點。

這是我的 xpath 表達式,xmlChar xpath = (xmlChar ) (".//way/*[@k="highway"]/..");

我已經在這個網站上測試過https://www.freeformatter.com/xpath-tester.html#ad-output但是它給了我想要的結果。

Element='<way changeset="4768013"
     id="4217107"
     timestamp="2010-05-21T17:45:57Z"
     uid="83557"
     user="Esperanza36"
     version="5"
     visible="true">
  <nd ref="25033470"/>
  <nd ref="25033531"/>
  <tag k="cycleway" v="opposite"/>
  <tag k="highway" v="residential"/>
  <tag k="maxspeed" v="30"/>
  <tag k="name" v="Rue Louis Thuillier"/>
  <tag k="oneway" v="yes"/>
 </way>'
.
.
.

...

所以這意味着我的 xpath 表達式是正確的,但問題是當我嘗試在我的 c 程序上使用它時,它給了我“沒有結果”。

我在互聯網上做了一些研究,但是關於它的文章很少,有人說這是因為命名空間問題,但我解析的 osm 文件沒有任何命名空間屬性,有人可以幫我解決一下嗎? 非常感謝!

這是我用於測試的代碼test.c ,您可以在以下位置找到測試文件: https://github.com/cblberlin/4M016_Projet/blob/master/test/5eme_petit.osm

#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>

xmlDocPtr
getdoc (char *docname) {
    xmlDocPtr doc;
    doc = xmlParseFile(docname);
    
    if (doc == NULL ) {
        fprintf(stderr,"Document not parsed successfully. \n");
        return NULL;
    }

    return doc;
}

xmlXPathObjectPtr getnodeset (xmlDocPtr doc, xmlChar *xpath)
{

    xmlXPathContextPtr context;
    xmlXPathObjectPtr result;

    context = xmlXPathNewContext(doc);

    if (context == NULL) {
        printf("Error in xmlXPathNewContext\n");
        return NULL;
    }

    result = xmlXPathEvalExpression(xpath, context);
    xmlXPathFreeContext(context);

    if (result == NULL) {
        printf("Error in xmlXPathEvalExpression\n");
        return NULL;
    }

    if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
        xmlXPathFreeObject(result);
                printf("No result\n");
        return NULL;
    }

    return result;
}


int
main(int argc, char **argv) {

    char *docname;
    xmlDocPtr doc;
    xmlChar *xpath = (xmlChar*) (".//way/*[@k=\"highway\"]/..");
    xmlNodeSetPtr nodeset;
    xmlXPathObjectPtr result;
    int i;
    xmlChar *keyword;
        
    if (argc <= 1) {
        printf("Usage: %s docname\n", argv[0]);
        return(0);
    }

    docname = argv[1];
    doc = getdoc(docname);
    result = getnodeset (doc, xpath);
    if (result) {
        nodeset = result->nodesetval;
        for (i=0; i < nodeset->nodeNr; i++) {
            keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
        printf("keyword: %s\n", keyword);
        xmlFree(keyword);
        }
        xmlXPathFreeObject (result);
    }
    xmlFreeDoc(doc);
    xmlCleanupParser();
    return (1);
}

gcc -std=c99 -Wall -I/include/libxml test.c -o test.exe -lm -lxml2

這個命令編譯,和

./test.exe 5eme_petit.osm

執行它,我得到

No result

請嘗試以下 XPath 表達式:

/osm/way[tag/@k='highway']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM