2010-06-28 9 views
11

Burada, sisteminizde libxml2'nin kurulu olduğu varsayılarak, gcc file.c -lxml2 kullanarak uyarı vermeyen bir kod yapıştırıyorum.libxml2 hatası

#include <libxml/parser.h> 
#include <libxml/xpath.h> 
#include <assert.h> 
#include <libxml/tree.h> 
#include <libxml/xpathInternals.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; 
    } 

    if(xmlXPathRegisterNs(context, BAD_CAST "new", BAD_CAST "http://www.example.com/new") != 0) { 
     fprintf(stderr,"Error: unable to register NS with prefix"); 
     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*) "/new:book/section1"; 
    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); 
} 

Sorunum aşağıdaki XML

<?xml version="1.0" encoding="UTF-8"?> 
<book xmlns="http://www.example.com/new"> 
    <section1>Sec_1</section1> 
    <section2>Sec_2</section2> 
</book> 

kitap elemanı o öğenin içinde bir ad alanını tanımlar ayrıştırmak istiyor olmasıdır. Xpath/book/section1 değerine yazdırmak istiyorum ve NULL döndürür. Öğeyi bir ad alanı altında döndürmeye çalıştığımda da hatalar alıyorum, yani/new: book/section1

Ad alanı öneklerini doğru kullanmıyorum çünkü kodumun başarısız olduğunu varsayalım. Zamanım tükendi. Lütfen yardım eder misiniz?

cevap

2

bu, varsayılan ad alanı ile ilgili bir sorundur. İhtiyacınız olan bir yolu eşleştirmek için:/new: tag ve benzeri

3

Bu, libXml kitaplığının rahatsız edici bir hatasıdır.

xmlns = "http://www.example.com/new"

İki seçenek: cateof tarafından belirtildiği gibi, sorun varsayılan ad alanı beyanıdır
(1) bu beyanı kurtulmak kitap etiketiniz veya (2) bir ad verin ve bu adı etiketlerinizde kullanın.

örn.

xmlns: Yeni = "http://www.example.com/new"

Sonra etiketleri tüm benziyor:

yeni: yeni kitap: vb section1

ve .

+2

mümkün anlatmak mı 'bazı ad üzerine tekrarlamaktan kaçınmak için/bir belgedeki tüm öğeler için örtülü varsayılan olduğunu libxml' ve XPath sorguları üzerinde? – SasQ

28

Libxml doğru XML/XPATH özelliklerine uygun çünkü bir sorun, ben , here öğrendim olarak gerçekten Libxml bir başarısızlık değil, ortaya çıktı.

R Bourdeau tarafından önerilen çözümler doğrudur, ancak ayrıştırmakta olduğunuz xml belgesinin denetimi varsa.

XPATH sorgusunun içeriği, xml belgesindeki ad alanı niteleyicilerinden bağımsız içeriğidir. Varsayılan ad alanı tüm alt etiketleri bir ad alanına zorlar; belgesinde belgesine gereksinim duymazlar, ancak xpath sorgusunda kalifiye olmalıdır. Neyse ki, ad alanını libXml ile new olarak kaydettiniz, bu yüzden cateof'in çözümü çalışmalıdır.

xmlXPathRegisterNs(context, BAD_CAST "new", BAD_CAST "http://www.example.com/new" 

xmlChar *xpath = (xmlChar*) "/new:book/new:section1"; 

ben görünürlük için buraya xml inlining ediyorum:

<?xml version="1.0" encoding="UTF-8"?> 
<book xmlns="http://www.example.com/new"> 
    <section1>Sec_1</section1> 
    <section2>Sec_2</section2> 
</book> 
+2

Bu, gerçekte neler olduğunu ve nasıl çözüleceğini açıklayan XPath ve ad-alanı ile ilgili ilk cevaptır. Saygılarımla arkadaşım. –