C++ 如何从ptree异常中获取xml行号

C++ 如何从ptree异常中获取xml行号,c++,xml,exception,boost,ptree,C++,Xml,Exception,Boost,Ptree,我使用boost ptree读取如下xml文件: ptree myTree; ... /*open xml file*/ try{ myTree.get<string>(s); } catch(boost::exception const& ex) { /*get useful info!*/ } ptreemytree; ... /*打开xml文件*/ 试一试{ myTree.get(s); } 捕获(boost::异常常量和ex) { /*获取有用的信息*/

我使用boost ptree读取如下xml文件:

ptree myTree;
... /*open xml file*/
try{
    myTree.get<string>(s);
}
catch(boost::exception const&  ex)
{
/*get useful info!*/
}
ptreemytree;
... /*打开xml文件*/
试一试{
myTree.get(s);
}
捕获(boost::异常常量和ex)
{
/*获取有用的信息*/
}
我知道我可以使用
what()


有没有办法获取更多有用的信息,如xml中与呼叫相关的行号?

如果您想检测格式错误的xml(与xml文档不同,xml文档不包含您期望的值,在这种情况下行号无法获取):


属性树不再有行号的概念。基本上它只是一棵可移植的树。它不知道它的内容是从文件中解析出来的,还是以编程方式添加的,还是不知从何而来的。因此,当树不包含您要查找的值时,无法获取行号

您可能需要考虑的事项:

  • 改进XML模式以捕获解析时丢失的信息。正如@JohnZwinck已经指出的,在解析时行号仍然存在。您完全可以排除“创建xml的人决定改变[结构上的任何东西]”这样的可能性。
    听起来好像是他们负责决定XML的外观。即使在这种情况下,您的程序仍然希望XML以某种方式形成,以便用它做有意义的事情。这就是你的模式发挥作用的地方。现在,如果他们决定更改他们的模式,您将立即注意到与您设计的模式不匹配的地方
  • 使用另一个变量
    get
    。如果所需数据不存在,有许多变体允许您指定默认值、获取null或执行其他操作。
    您的try-instant-catch-debug-continue代码模式表明,您不完全确定预期的数据是什么,并且如果数据不在那里,则不重要。例外情况适用于例外情况。我觉得这不是一个

我无法帮助您确定行号,但我想补充一点,大多数解析器都可以自由地以不同的方式对元素进行排序(),因此在我看来,行号并不是一个很好的信息。我假设您需要实现一个自定义版本的ptree,该版本具有存储行号和字符串的数据类型。然后,您必须专门化xml解析器来处理新的特殊类型。但是,我也从未使用过ptree或它的xml解析器,所以可能我错了:)谢谢,但实际上我正在尝试检测xml是否没有我期望的值。xml没有格式错误,因为它通过了架构验证。@yonigo那么我不确定我是否理解你的问题,你想得到什么的行号?@yonigo:那么你需要更新你的架构,使其更严格,并在解析时使用它。Boost PropertyTree没有根据自定义模式验证XML的功能,因此我建议先根据模式对其进行一次解析,如果通过,则将其传递给PropertyTree。就我个人而言,我会考虑使用松弛模式,但有多种选择,你可能知道。好,我对我的问题更清楚,我的XML是有效的,它的值是有效的。在我的代码中,我读取如下xml值:myTree.get(s);但有时“s”不是myTree中某个字段的名称——可能是因为我的代码中有一个bug,也可能是创建xml的人决定将名称“s”更改为其他名称。我不想得到一个未知的异常,而是想得到发生在XMLOk行号上的行号,所以我想我不能做我想做的事情!无论如何谢谢你
#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;
  }
}
$ a.out t.xml
error in file t.xml at line 10