Нужна помощь с функцией C ++ для анализа / отображения сериализации XML

Мне нужна помощь, чтобы моя сериализация XML работала правильно. Прямо сейчас у меня есть две функции, которые читают мой XML-файл, char за char. Прямо сейчас они успешно обнаруживают и сохраняют элементы, а также сохраняют содержимое элементов в виде переменной. У меня есть функция print иерархии элементов, и они успешно показывают содержимое, которое они содержат.

Моя проблема: я не могу заставить функцию правильно идентифицировать конечный тег для элементов! Например, когда синтаксический анализ достигает тега end элементов, он обнаруживает его как элемент, а не как конец элемента.

Извините за весь текст и длину кода. Я стараюсь быть максимально тщательным. Заранее спасибо!

Это то, что отображается при компиляции и запуске кода. Обратите внимание, что есть элементы, которые не равны ничему

XML.World.Item.name = silver key
XML.World.Item.properties.property = metal
XML.World.Item.properties.property = silver
XML.World.Item.properties =
XML.World.Item.weight = 1
XML.World.Item.displayChar = )
XML.World.Item.value = 10
XML.World.Item.rarity = 5
XML.World.Item =
XML.World.Creature.name = orc
XML.World.Creature.properties.property = orcish
XML.World.Creature.properties.property = humanoid
XML.World.Creature.properties =
XML.World.Creature.level = 2
XML.World.Creature.maxHP = 15
XML.World.Creature.displayChar = o
XML.World.Creature =
XML.World =

Мой XML-файл называется world.xml, и это код XML, который он содержит:

<?xml version="1.0" encoding="UTF-8"?>
<World>
<Item>
<name>silver key</name>
<properties>
<property>metal</property>
<property>silver</property>
</properties>
<weight>1</weight>
<displayChar>)</displayChar>
<value>10</value>
<rarity>5</rarity>
</Item>
<Creature>
<name>orc</name>
<properties>
<property>orcish</property>
<property>humanoid</property>
</properties>
<level>2</level>
<maxHP>15</maxHP>
<displayChar>o</displayChar>
</Creature>
</World>

Вот мой используемый код — XMLSerialization.h, XMLSerialization.cpp и main.cpp:

XMLSerialization.h

#include <iostream>
#include <string>
#include <fstream>

class XMLSerialization {

public:
virtual bool parseElement(std::istream & xmlFile, std::string hierarchy$
virtual bool parseXML(std::istream & xmlFile);

private:
//none
};

XMLSerialization.cpp

#include "XMLSerialization.h"#include <string>

using namespace std;
bool XMLSerialization::parseElement(istream & xmlFile, string hierarchy){
char c; // the character as we reach it
string elementName;

//reads char by char, checking for '>' at the end of the tag

do {
c = xmlFile.get();
if (c != '>')
elementName.push_back(c);
}
while (c != '>');

string content; //holds the non-element content of the element

while (true){
c = xmlFile.get();
if (c == '<'){
if (xmlFile.peek() == '/'){
xmlFile.get();
string endTag; //holds the end tag as its read

while(c != '>'){
c = xmlFile.get();
if (c != '>'){
endTag.push_back(c);
}
}

if (endTag != elementName){
cout<<"Tag name mismatch! "<<endTag<<
" differs from "<<elementName
<<"."<<endl;
return false;
}

//output what is known. Where we are in the
//file, current element, and its content
cout<<hierarchy<<"."<<elementName<<" = "<<
content<<endl;
return true;
}
else {
//read in '<' and was NOT an end tag. c is at
//the first char after < so function calls
//on itself again. Passing hierarchy and current
//element name so next element knows where it
//is in the xmlFile.
if (!parseElement(xmlFile, hierarchy + "." + el$
return false;
}
}
}

else {
//c is not '<' so its content. Also ignores EOL
if (c != '\n'){
content.push_back(c);
}
}
}

return true;
}// checks for a valid XML Header
bool XMLSerialization::parseXML(istream & xmlFile){
char c; // char to hold the character as we reach it

//get character while the character != '<'
do {
c = xmlFile.get();
}
while (c != '<');

//checks the character after the '<'
if (xmlFile.get() != '?'){
cout<<"Invalid XML Header! Does not begin with '<?'"<<endl;
return false;
}
//continues through header look for '?'
do {
c = xmlFile.get();
}
while (c != '?');

// checks for the header ending with ?>
if (xmlFile.get() != '>'){
cout<<"Invalid XML Header! Does not end with '?>'"<<endl;
return false;
}

// go through character until the first tag after the header
do {
c = xmlFile.get();
}
while (c != '<');

// at the first character after the opening '<' of the tag
// call parseElement
return parseElement(xmlFile, "XML");
}

main.cpp

#include "XMLSerialization.h"#include <fstream>
#include <iostream>
using namespace std;

int main(int argc, char * argv[]){
cout<<"________________________"<<endl;
cout<<"XML TESTING"<<endl<<"________________________"<<endl<<endl;
ifstream xmlFile;
xmlFile.open("world.xml");
XMLSerialization test;
test.parseXML(xmlFile);
xmlFile.close();
return 0;
}

0

Решение

Пожалуйста, ради любви ко всему святому, используйте правильный синтаксический анализатор XML. Ты не пожалеешь об этом. я очень рекомендую libxml2.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]