0

How to retrieve node and attribute values from xml file in C++ using libxml2 by using xpath ?

Thanks in advance, Bhargava

1
  • 1
    Did you see the examples provided on the libxml website ? Commented Nov 14, 2010 at 11:26

3 Answers 3

8

Since this is tagged C++ I'll assume you can use the libxml++ library bindings.

I wrote a simple program that:

  • Parse the document using a DomParser
  • Make an XPath query using find() on the document root node to get to the attribute.
  • Cast the first node of the XPath result to an Attribute node
  • Get that attribute string value using get_value()
  • Display that value

Here's the code:

#include <iostream>
#include <libxml++/libxml++.h>

using namespace std;
using namespace Glib;
using namespace xmlpp;

int main(int argc, char* argv[])
{
    // Parse the file
    DomParser parser;
    parser.parse_file("file.xml");
    Node* rootNode = parser.get_document()->get_root_node();

    // Xpath query
    NodeSet result = rootNode->find("/root/a/b/@attr");

    // Get first node from result
    Node *firstNodeInResult = result.at(0);
    // Cast to Attribute node (dynamic_cast on reference can throw [fail fast])
    Attribute &attribute = dynamic_cast<Attribute&>(*firstNodeInResult);

    // Get value of the attribute
    ustring attributeValue = attribute.get_value();

    // Print attribute value
    cout << attributeValue << endl;
}

Given this input:

<!-- file.xml -->
<root>
  <a>
    <b attr="I want to get this"> </b>
  </a>
</root>

The code will output:

I want to get this

To compile this on an Unix system:

c++ `pkg-config libxml++-2.6 --cflags` `pkg-config libxml++-2.6 --libs` file.cpp
Sign up to request clarification or add additional context in comments.

5 Comments

thans for reply, but i need same thing only in libxml2
I might be wrong about this, but isn't version 2 of libxml++ a wrapper for libxml2? So in practice this is libxml2. Is there any reasons that you cannot use a wrapper?
I don't know about wrappers so i didn't use it and May i know the use of wrappers?
Got a bunch of undefined reference when I tried to compile. Compiling like this fixed the issue for me (sorry the stupid lowercase tilde in stack overflow is screwing up the formatting...) <command start>c++ file.cpp pkg-config libxml++-2.6 --cflags pkg-config libxml++-2.6 --libs<command end>
Then trying to run the program errors: terminate called after throwing an instance of 'std::bad_cast'
1

sp1.xml:

<users noofids="1">
        <user user="vin" password="abc"/>
</users>

Program:

#include <libxml/xpath.h>
#include <libxml/tree.h>
#include <iostream>
using namespace std;

int
main (int argc, char **argv)
{
  char ID[25];
  xmlInitParser ();
  //LIBXML_TEST_VERSION
  xmlDoc *doc = xmlParseFile ("sp1.xml");
  xmlXPathContext *xpathCtx = xmlXPathNewContext (doc);
  xmlXPathObject *xpathObj =
    xmlXPathEvalExpression ((xmlChar *) "users/user", xpathCtx);
  xmlNode *node = xpathObj->nodesetval->nodeTab[0];
  xmlAttr *attr = node->properties;
  while (attr)
    {
      //if(!xmlStrcmp(attr->name,(const xmlChar *)"noofids"))
      //sprintf(ID,"%s",attr->children->content);
      std::cout << "Attribute name: " << attr->name << "  value: " << attr->
    children->content << std::endl;
      attr = attr->next;
    }
  //std::cout<<"ID: "<<ID<<endl;
  return 0;
}

i got output by trying by my own

Comments

1

This is an example of how to get the value for the xpath you are trying to evaluate with libxml++.

Based on Alexandre Jasmin's answer but his only shows how to print an xpath attribute and it's not trivial to figure out how to print the Node's value because you have to cast it to a specific object (also his answer throws an exception).

#include <iostream>
#include <libxml++/libxml++.h>

using namespace std;
using namespace Glib;
using namespace xmlpp;

int main(int argc, char* argv[])
{
    // Parse the file
    DomParser parser;
    parser.parse_file("sample.xml");
    Node* root = parser.get_document()->get_root_node();

    // Xpath query
    NodeSet result = root->find("/root/ApplicationSettings/level_three");

    // Get first element from result
    Element *first_element = (Element *)result.at(0);

    // Print the content of the Element
    cout << first_element->get_child_text()->get_content() << endl;
}

sample.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
    <ApplicationSettings>
        <level_three>hello world</level_three>
    </ApplicationSettings>
</root>

compile

g++ test.cpp -o test `pkg-config libxml++-2.6 --cflags` `pkg-config libxml++-2.6 --libs`

run

./test

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.