这是我第一次使用XML和使用C ++目前我正在试图返回一个整数(实际上要返回双,但没有得到那么远,)从XML文件。 我使用RAPIDXML及以下实现:
所有的文件都在同一目录下。
XML(firstxml.xml):
<?xml version="1.0"?>
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="firstxsd.xsd">
<A>10</A>
<B>Hello</B>
</test>
XML的架构(firstxsd.xsd):
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="test">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:integer" name="A"/>
<xs:element type="xs:string" name="B"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
C ++(test.cxx):
#include <iostream>
#include <sstream>
#include <fstream>
#include "rapidxml-1.13/rapidxml.hpp"
#include "rapidxml-1.13/rapidxml_print.hpp"
#include <string>
#include <stdio.h>
#include <vector>
int main(int argc, char* argv[])
{
std::ifstream file ("firstxml.xml");
if (file.is_open())
{
file.seekg(0,std::ios::end);
int size = file.tellg();
file.seekg(0,std::ios::beg);
char* buffer = new char [size];
file.read (buffer, size);
file.close();
rapidxml::xml_document<> doc;
doc.parse<0>(buffer);
rapidxml::xml_node<> *node = doc.first_node()->first_node();
//Line which results in error
std::cout << node->value()*10 << std::endl;
delete[] buffer;
}
}
错误:
test.cxx:52:31: error: invalid operands of types ‘char*’ and ‘int’ to binary ‘operator*’
从我所阅读在线教程,我相信我正确构建的文件,所以解析成由节点A的C ++文件中的值应为整数。 有一两件事我注意到的是,在RAPIDXML手册的价值规范()如下:
Ch* value() const;
Description: Gets value of node. Interpretation of value depends on type of node. Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. Use value_size() function to determine length of the value.
Returns: Value of node, or empty string if node has no value.
因此,函数的定义说,它总是返回一个字符指针,但行“的价值解读取决于类型的节点”意味着它返回一个类型相关的值。
感谢您抽出时间来看看我的问题,任何帮助是极大的赞赏,
保罗。
这是很难说这个短语是什么“的价值解读依赖于节点的类型”的意思。 如果函数返回Ch pointer
后总是回到这样的指针或导致运行时异常,如果库的开发者提供了这种功能。 当然,当您尝试乘以Ch*
由一个int你编译时错误。
一个函数可以返回一个类型取决于调用上下文的唯一方法就是使用一些特殊的用户定义的返回类型( VARIANT
或类似的东西)。 在我看来,这Ch
仅仅是基本的字符类型库(的pseudonim char
或可能wchar_t
)。
因此,通过该“解释......”通知的开发人员可能意味着用户必须在字符串的正确解释,根据到节点(而这又依赖于用户定义的架构)的类型。
到数的C-字符串表示转换为对应的类型,你可以使用从标准C库函数,如atoi()
转换为int), atof()
增加一倍)等。
我猜你要访问“属性”值,所以这样做...
COUT << “我的第一个节点的名称是:” << doc.first_node() - >名称()<< “\ n”;
xml_node <> *节点= doc.first_node( “foobar的”);
COUT << “节点foobar的具有值” <<节点 - >值()<< “\ n” 个;
对于(xml_attribute <> * ATTR =节点 - > first_attribute(); ATTR; ATTR = attr-> next_attribute())
{COUT << “节点foobar的具有属性” << attr->名称()<<““;
cout << "with value " << attr->value() << "\n";
}
也看看rapidXML教程...
http://rapidxml.sourceforge.net/manual.html它很容易!
有人纠正我,如果我错了,我相信RapidXML只会给你值作为某种形式的字符串,由于其就地解析性质。 类模板可能是用于处理焦炭VS宽字符或类似的东西,我不知道,我只用字符。
我所做的处理提取的值是一个辅助类添加到rapidxml_utils.hpp(可能真的已经把它的任何地方,但它是有道理的存在),还有一些静态函数解析一个XML节点或属性的值(如果默认值它不解析)。
这些佣工让我做的东西,如:
int Height = xml_helper::GetNodeInt(cur_node->first_node("Height"), 48);
int Width = xml_helper::GetNodeInt(cur_node->first_attribute("Width"), 128);
在你的情况你可以使用我的助手类是这样的:
//Line which results in error (altered to use my helper class, if node absent or not parse as integer uses zero)
std::cout << xml_helper::GetNodeInt(node, 0)*10 << std::endl;
我的助手类看起来像这样(我用的sscanf得到验证某种程度):
class xml_helper
{
public:
// a couple little helpers, lets you do this:
// int Height = xml_helper::GetNodeInt(cur_node->first_node("Height"), 48);
// int Width = xml_helper::GetNodeInt(cur_node->first_node("Width"), 128);
static int GetNodeInt(rapidxml::xml_base<>* node, int DefaultValue)
{
int temp;
try
{
if (node == 0) return DefaultValue;
if (sscanf(node->value(), "%d", &temp) != 1) return DefaultValue;
return temp;
//return atoi(node->value());
}
catch (...) { return DefaultValue; }
}
static unsigned int GetNodeUInt(rapidxml::xml_base<>* node, unsigned int DefaultValue)
{
unsigned int temp;
try
{
if (node == 0) return DefaultValue;
if (sscanf(node->value(), "%u", &temp) != 1) return DefaultValue;
return temp;
//return strtoul(node->value(), NULL, 0);
}
catch (...) { return DefaultValue; }
}
static long long GetNodeLL(rapidxml::xml_base<>* node, long long DefaultValue)
{
long long temp;
try
{
if (node == 0) return DefaultValue;
if (sscanf(node->value(), "%lld", &temp) != 1) return DefaultValue; //C99 covers %lld
return temp;
//return strtoll(node->value(), NULL, 0); //C++11, could use _strtoi64 in VS until then?
}
catch (...) { return DefaultValue; }
}
static double GetNodeDouble(rapidxml::xml_base<>* node, double DefaultValue)
{
double temp;
try
{
if (node == 0) return DefaultValue;
if (sscanf(node->value(), "%lf", &temp) != 1) return DefaultValue; // could use strtod
return temp;
}
catch (...) { return DefaultValue; }
}
static std::string GetNodeStr(rapidxml::xml_base<>* node, std::string DefaultValue)
{
try
{
if (node == 0) return DefaultValue;
return node->value();
}
catch (...) { return DefaultValue; }
}
};
希望这可能有助于您或他人使用rapidxml和需要一个快速的方法来获得整数,双打,或任何出节点。 这当然可以扩展到其他类型的,我只有到目前为止,我需要在那里现在的类型,但你得到它的要点。