2009-07-07 16 views
6

Ich arbeite an einem Parser, um Daten aus einer XML-Datei zu erhalten. Ich verwende libxml2, um Daten zu extrahieren. Ich bin nicht in der Lage, die Attribute von Knoten zu bekommen. Ich habe nur nb_attributes gefunden, um die Anzahl der Attribute zu erhalten.So erhalten Sie Attribute von einem Knoten in libxml2

Antwort

1

Versuchen Sie so etwas wie:

xmlNodePtr node; // Some node 
NSMutableArray *attributes = [NSMutableArray array]; 

for(xmlAttrPtr attribute = node->properties; attribute != NULL; attribute = attribute->next){ 
    xmlChar *content = xmlNodeListGetString(node->doc, attribute->children, YES); 
    [attributes addObject:[NSString stringWithUTF8String:content]]; 
    xmlFree(content); 
} 
+0

Hallo Mat. Ich fand Ihren Code hilfreich, um die Werte von Attribut herauszufinden. Aber es gibt den Wert nur für den ersten Knoten. Wie man Werte auch für die folgenden Knoten erhält. ??.. Danke im Voraus. – NiKKi

+0

Sollten "Knoten-Kinder" nicht zu "Attribut-> Kindern" werden? –

+0

Ja sollte es :) Siehe auch @ Matthew Lowe, er bemerkte den Fehler früher. Ich habe die Antwort aktualisiert (2.5 Jahre später;)) – Joost

8

Ich denke joostk gemeint Attribut-> Kinder, so etwas wie dieses geben:

xmlAttr* attribute = node->properties; 
while(attribute) 
{ 
    xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1); 
    //do something with value 
    xmlFree(value); 
    attribute = attribute->next; 
} 

Sehen, ob das für Sie arbeitet.

+0

Hallo Mat. Ich fand Ihren Code hilfreich, um die Werte von Attribut herauszufinden. Aber es gibt den Wert nur für den ersten Knoten. Wie man Werte auch für die folgenden Knoten erhält. ??.. Danke im Voraus. – NiKKi

+0

Sie können über Knoten auf die gleiche Weise iterieren, wie Sie über Attribute iterieren: node = node-> next. –

2

Ich glaube, ich gefunden, warum Sie nur 1 Attribut bekam (zumindest ist es mir passiert ist).

Das Problem war, dass ich Attribute für den ersten Knoten lesen, aber das nächste ist ein Textknoten. Ich weiß nicht warum, aber node-> properties gibt mir einen Verweis auf einen nicht lesbaren Teil des Speichers, so dass es abgestürzt ist.

war meine Lösung Knotentyp zu überprüfen (Element 1)

Ich bin ein Leser mit, so:

xmlTextReaderNodeType(reader)==1 

Der gesamte Code, den Sie es aus http://www.xmlsoft.org/examples/reader1.c und fügen dieses

bekommen
xmlNodePtr node= xmlTextReaderCurrentNode(reader); 
if (xmlTextReaderNodeType(reader)==1 && node && node->properties) { 
    xmlAttr* attribute = node->properties; 
    while(attribute && attribute->name && attribute->children) 
    { 
     xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1); 
     printf ("Atributo %s: %s\n",attribute->name, value); 
     xmlFree(value); 
     attribute = attribute->next; 
    } 
} 

50.

0

Linie Wenn Sie SAX-Methode startElementNs verwenden (...), ist diese Funktion, was Sie suchen:

xmlChar *getAttributeValue(char *name, const xmlChar ** attributes, 
      int nb_attributes) 
{ 
int i; 
const int fields = 5; /* (localname/prefix/URI/value/end) */ 
xmlChar *value; 
size_t size; 
for (i = 0; i < nb_attributes; i++) { 
    const xmlChar *localname = attributes[i * fields + 0]; 
    const xmlChar *prefix = attributes[i * fields + 1]; 
    const xmlChar *URI = attributes[i * fields + 2]; 
    const xmlChar *value_start = attributes[i * fields + 3]; 
    const xmlChar *value_end = attributes[i * fields + 4]; 
    if (strcmp((char *)localname, name)) 
     continue; 
    size = value_end - value_start; 
    value = (xmlChar *) malloc(sizeof(xmlChar) * size + 1); 
    memcpy(value, value_start, size); 
    value[size] = '\0'; 
    return value; 
} 
return NULL; 
} 

Verbrauch:

char * value = getAttributeValue("atrName", attributes, nb_attributes); 
// do your magic 
free(value); 
0

Der einfachste Weg, ich mit libxml2 gefunden (über libxml ++ in C++) war die eval_to_XXX Methoden zu verwenden. Sie werten einen XPath-Ausdruck aus, daher müssen Sie die -Syntax verwenden.

Zum Beispiel:

std::string get_property(xmlpp::Node *const &node) { 
    return node->eval_to_string("@property") 
} 
+0

Der effizientere und direktere Weg mit libxml ++ ist 'return std :: string (dynamic_cast (Knoten) -> get_attribute_value (" property "))'. Außerdem ist Ihre Parameterdeklaration seltsam: Sie deklarieren 'node' als Verweis auf einen const-Zeiger auf nicht-const' xmlpp :: Node'. Nützlicher wäre: 'const xmlpp :: Node * node' – maxschlepzig

Verwandte Themen