使用libxml2 sax解析器获取价值错误
Get value error with libxml2 sax parser
我正在尝试使用libxml2的sax接口解析XML文件。有时它效果很好,但是随后我更改了XML中的2行顺序(在Coure仍然有效),而解析后有些值无效。我正在使用StartElementNSSAX2FUNC进行StartElement,它具有一个参数const xmlchar **属性,该属性存储了当前元素的属性。
在开始方法的开头,我创建了一个简单的对象来处理属性这是类的代码:
class XMLElementAttributes {
public:
static const int AttributeArrayWidth = 5;
static const int LocalNameIndex = 0;
static const int PrefixIndex = 1;
static const int URIIndex = 2;
static const int ValueIndex = 3;
static const int EndIndex = 4;
XMLElementAttributes( int nb_attributes, const xmlChar **attributes) :
nb_attributes(nb_attributes),
attributes(attributes){
}
xmlChar* getLocalName( int index ) const {
return (xmlChar*)attributes[ AttributeArrayWidth * index + LocalNameIndex];
}
xmlChar* getValue( int index ) const{
return (xmlChar*)std::string(attributes[ AttributeArrayWidth * index + ValueIndex],attributes[ AttributeArrayWidth * index + EndIndex]).c_str();
}
int getLength() const{
return nb_attributes;
}
private:
int nb_attributes;
const xmlChar ** attributes;
};
(xmlchar是typedef unsigned char xmlchar)
然后,如果我需要存储属性的值,我将使用此Staic方法克隆它(我还尝试使用libxml2的XMLSTRDUP,结果是相同的):
xmlChar* cloneXMLString(const xmlChar* const source) {
xmlChar* result;
int len=0;
std::cout<<"source"<<std::endl;
while (source[len] != ' '){
std::cout<<(void*)&source[len] << ": " << source[len] <<std::endl;
len++;
}
std::cout<<std::endl;
std::cout<<"result, "<<std::endl;
result = new xmlChar[len+1];
for (int i=0; i<len; i++){
result[i] = source[i];
std::cout<<(void *)&source[i] << ": "<< source[i] << std::endl;
}
std::cout<<std::endl;
result[len] = ' ';
return result;
}
它的工作原理为99%,但有时最终的结果包含与源的相似之处。这是一个示例输出(输入为ABCDEF, 0终止):
source
0x7fdb7402cde8: a
0x7fdb7402cde9: b
0x7fdb7402cdea: c
0x7fdb7402cdeb: d
0x7fdb7402cdec: e
0x7fdb7402cded: f
result,
0x7fdb7402cde8: !
0x7fdb7402cde9:
0x7fdb7402cdea:
0x7fdb7402cdeb:
0x7fdb7402cdec: x
0x7fdb7402cded:
我这样称呼它:
xmlChar* value = cloneXMLString(attributes.getValue(index));
因此,虽然源的地址没有更改,但值确实如此。XML文件的解析继续没有任何问题,克隆后的下一个值再次有效。
如果XML文件未更改,则错误始终处于同一元素和参数。例如,如果我更改XML,例如:
<somenodes a="arg1" b="arg2">
<node c="abc" d="def" />
<node c="ghi" d="jkl" />
</somenodes>
to
<somenodes a="arg1" b="arg2">
<node c="ghi" d="jkl" />
<node c="abc" d="def" />
</somenodes>
错误出现在其他地方,或者消失,解析效果很好。是什么可能导致的?
编辑:
我的开始元素方法:
void MyParser::startElement( void * ctx,
const xmlChar * localName,
const xmlChar * prefix,
const xmlChar * URI,
int nb_namespaces,
const xmlChar ** namespaces,
int nb_attributes,
int nb_defaulted,
const xmlChar ** attrs ){
XMLElementAttributes attributes ( nb_attributes, attrs );
switch ( state ) {
case Somestate:
if ( xmlStrcmp( localName, StrN("SomeName").xmlCharForm() ) == 0) {
someVar = new SomeObject(attributes);
}
break;
...
}
}
strn从char*创建xmlchar。SomeVar是MyParser类中的一个高级领域(开头也是静态的)。在某些对象的构造函数中,我试图获得这样的属性值:
class SomeObject {
public:
SomeObject( XMLElementAttributes &attributes){
for (int i=0; i< attributes.getLength(); i++) {
xmlChar* name = attributes.getLocalName(i);
if ( xmlStrcmp( name, StrN("somename").xmlCharForm()) == 0 ) {
somename = cloneXMLString(attributes.getValue(i));
}
...
}
}
};
很明显,源没有指向有效的内存。这可能是因为内存已经被释放,也可能是因为它指向在已经退出的函数中声明的堆叠内存。
这种记忆可能以一种不可预测的方式覆盖,这就是您在这里看到的。
需要查看更多上下文,尤其是您调用 cloneXMLString
的方式以及您传递给此功能的内存位置,以获得更详细的答案。
- 在 Eclipse: "error: no match for 'operator='" 中获取错误消息
- 函数从指针 c++ 中获取错误的值并返回错误的答案
- 使用 C++ iOS::ate 获取错误的文件大小
- 从谷歌日历API获取错误请求
- 获取错误:之前在此处声明的布尔队列的编辑<T>
- 由于树类中的模板,正在获取错误
- 失败时如何获取错误原因curl_easy_init
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- 使用 WindowSetup 类变量获取错误
- 通过查找一对项目的代码获取错误的输出,在给定的总和相等的给定列表中列表
- 带有边界获取错误的 HTTP POST
- 尝试重新连接到服务器时获取错误提升 asio 连接超时
- 使用 C/C++ 获取错误消息MSB6006错误代码 2
- 在此程序中获取错误:检查两个数组是否相等
- 获取错误:在“(”标记之前进行预期的构造函数、析构函数或类型转换
- (C++)在按位 OR 操作时获取错误"Illegal instruction (core dumped)"
- 获取错误mf_e_streamsinks_fixed用于EVR -Windows Media Foundation
- urlmkgetSessionOption获取错误的用户
- Visual Studio C 2K15-在指针地址上获取错误
- 获取错误makefile:45:条件中的语法无效.停止