How can i get xml line number from ptree exception
Asked Answered
L

2

8

I am using boost ptree to read an xml file like this:

ptree myTree;
... /*open xml file*/
try{
    myTree.get<string>(s);
}
catch(boost::exception const&  ex)
{
/*get useful info!*/
}

I know I can use the what() function, but it produces an error and the strings I just sent.

Is there a way to get more useful information like the line numbers in the xml that are relevant to the call?

Ln answered 22/7, 2013 at 5:55 Comment(2)
I cant help you with that line number, but want to throw in, that most parsers are free to order your elements in a different way ( ibm.com/developerworks/xml/library/x-eleord/index.html ) so your line-number isnt a really good information in my eyesPalmate
I would assume you need to implement a custom version of ptree which has a data type which stores the line number as well as the string. Then you'll have to specialize the xml parser to deal with your new special type. But, I also have never used either ptree or its xml parser so maybe I'm wrong :)Jodee
E
2

If you want to detect malformed XML (as opposed to XML documents which simply don't contain the values you expect, in which case line numbers aren't feasible to obtain):

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

int main(int argc, char* argv[])
{
  boost::property_tree::ptree pt;
  try {
    read_xml(argv[1], pt);
  } catch (const boost::property_tree::xml_parser::xml_parser_error& ex) {
    std::cerr << "error in file " << ex.filename() << " line " << ex.line() << std::endl;
  }
}

Now given that t.xml is not a valid XML document:

$ a.out t.xml
error in file t.xml at line 10
Exegete answered 22/7, 2013 at 6:39 Comment(6)
thanks, but actually i am trying detect if the xml doesn't have the values i expect. the xml is not malformed because it passes through schema validation.Ln
@Ln then I'm not sure I understand your question, you want to get the line number of what?Byrle
@yonigo: Then you need to update your schema to be more strict, and use it when parsing. Boost PropertyTree has no facility to validate your XML against a custom schema, so I'd suggest parsing it once against the schema first, then passing it to PropertyTree if it passes. Personally I'd consider using RelaxNG for the schema, but there are multiple options as you probably know.Exegete
Ok ill be more clear about my question, My xml is valid and its values are valid. In my code I read the xml values like this: myTree.get<string>(s); But sometimes "s" is not a name of a field in myTree - It could be because i have a bug in my code, or it could be that the person creating the xml decided to change the name "s" to something else. Instead of getting an UNKNOWN EXCEPTION i would like to get the line number it happened atLn
The line number of the XMLLn
Let me get this straight: you want the line number in the XML file where a missing value is? As Charles Babbage said, "I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."Exegete
L
1

A boost::property_tree has no concept of line numbers anymore. Basically it is just an iterable tree. It doesn't know if its contents where parsed from a file, added programmatically or came out of nowhere. Therefore there is just no way to get a line number when the tree doesn't contain the values you are looking for.

Things you might want to consider:

  • Improve your XML schema to catch missing information on parse time. As @JohnZwinck already pointed out line numbers still exist while parsing. You should definitely be able to rule out "that the person creating the xml decided to change [anything structurally]" like this.
    You make it sound like they are in charge of deciding how the XML must look like. Even if this is the case your program still expects the XML to be formed in a certain way to do meaningful things with it. And this is where your schema comes into play. Now if they decide to change their schema you will instantly notice where there is a mismatch to the schema you designed for.
  • Use another variant of get<string>. There are many variant allowing you to specify default values, getting null, or do something else, if the data you are expecting does not exist.
    Your try-instant-catch-debug-continue code pattern suggests that you aren't entirely sure what data to expect and that it is noncritical if the data isn't there. Exceptions are for exceptional situations. It seemsmto me that this isn't one.
Library answered 22/12, 2013 at 19:38 Comment(1)
Ok, so i guess i cannot do what i want! Thanks anywayLn

© 2022 - 2024 — McMap. All rights reserved.