Я должен делать что-то принципиально неправильное. У меня есть тестовая программа, настроенная для чтения и отображения содержимого файла xml, чтобы я мог изучить и узнать, как данные хранятся и представлены. У меня есть огромные файлы xml, генерируемые электронными таблицами, которые управляют нашим сборочным оборудованием. В конечном итоге мне нужно переупорядочить, отредактировать и создать данные в этих файлах.
На данный момент я просто пытаюсь понять, почему PUGIXML, кажется, игнорирует данные узлов и узлы без атрибутов.
Это образец XML файла, который я создал, когда стало ясно, что я не нашел все в реальных файлах:
<Node1 attr11="attribute11"
attr12="attribute12"
attr13="attribute13"
attr14="attribute14"
attr15="attribute15"
attr16="attribute16">
<Node11 attr111="attribute111">
<Value1>value1</Value1>
<Value2>value2</Value2>
<Value3>value3</Value3>
<Value4>value4</Value4>
</Node11>
<Node12/>
<Node13></Node13>
<Node14 attr141="attribute141"
attr142="attribute142"
attr143="attribute143"
attr144="attribute144">
<Value1>value1</Value1>
<Value2>value2</Value2>
<Value3>value3</Value3>
<Value4>value4</Value4>
</Node14>
<Node15>
<Value1>value1</Value1>
<Value2>value2</Value2>
<Value3>value3</Value3>
<Value4>value4</Value4>
</Node15>
</Node1>
Вот частичный список обертки C++, которую я создаю вокруг PUGIXML для совместимости с существующим кодом:
class XMLFileImporter2
{
public:
// constructor
XMLFileImporter2( string strIn )
{
// stash the file name
m_strTheFileName = strIn;
// make the call to the pugi system
pugi::xml_parse_result result = m_xmlTheXML.load_file( m_strTheFileName.c_str() , pugi::parse_full );
m_strLastResultMessage = string( result.description() );
// did the xml read correctly?
m_bDidFileRead = ( m_strLastResultMessage == "No error" );
....
}
void test1( vector<string> &lstText )
{
// clear the vector
lstText.resize( 0 );
// interate through the xml data
for ( pugi::xml_node thisnode = m_xmlTheXML.first_child() ; thisnode ; thisnode = thisnode.next_sibling() )
{
testRecurse( thisnode , lstText , 0 );
}
}
void testRecurse( pugi::xml_node nodeIn , vector<string> &lstText , int iLevelIn )
{
// first, increment a local copy of the level
int iLocalLevel = iLevelIn + 1;
// temp vars
string strTemp , str1 , str2 , str3 , str4 , str5;
int iAttr = 0;
int iloop;
// build the attribute list for THIS node
for ( pugi::xml_attribute attr = nodeIn.first_attribute() ; attr ; attr = attr.next_attribute() )
{
// increment valid attribute count
iAttr++;
// init the string
strTemp = CUtility::makeStringFromInt( iLocalLevel ) + " : " + CUtility::makeStringFromInt( iAttr ) + " : ";
str1 = string( attr.name() );
str2 = string( attr.value() );
str3 = string( nodeIn.name() );
pugi::xml_node_type tNodeType = nodeIn.type();
str5 = getNodeType( tNodeType );
str4 = string( nodeIn.value() );
if ( str4 == "" ) str4 = "<blank>";
strTemp = strTemp + " Node Name = " + str3 + " Node Type = " + str5 + " Node Val = " + str4 + " Attr Name = " + str1 + " Attr Val = " + str2;
for ( iloop = 0 ; iloop < iLevelIn ; iloop++ )
strTemp = " " + strTemp;
// stash it
lstText.push_back( strTemp );
}
// recurse to any child nodes
for ( pugi::xml_node nextnode = nodeIn.first_child() ; nextnode ; nextnode = nextnode.next_sibling() )
{
testRecurse( nextnode , lstText , iLocalLevel );
}
}
...
};
Когда я создаю экземпляр моей оболочки, он заставляет документ участника PUGIXML загружать файл. Кажется, что это происходит без ошибок. После того, как я знаю, что это правда, я выполняю метод трассировки тестового элемента оболочки, чтобы сбрасывать всю структуру дерева узлов на вектор строки STL, и я выгружаю это в несортированный список. Это показывает мой список:
1 : 1 : Node Name = Node1 Node Type = node_element Node Val = <blank> Attr Name = attr11 Attr Val = attribute11
1 : 2 : Node Name = Node1 Node Type = node_element Node Val = <blank> Attr Name = attr12 Attr Val = attribute12
1 : 3 : Node Name = Node1 Node Type = node_element Node Val = <blank> Attr Name = attr13 Attr Val = attribute13
1 : 4 : Node Name = Node1 Node Type = node_element Node Val = <blank> Attr Name = attr14 Attr Val = attribute14
1 : 5 : Node Name = Node1 Node Type = node_element Node Val = <blank> Attr Name = attr15 Attr Val = attribute15
1 : 6 : Node Name = Node1 Node Type = node_element Node Val = <blank> Attr Name = attr16 Attr Val = attribute16
2 : 1 : Node Name = Node11 Node Type = node_element Node Val = <blank> Attr Name = attr111 Attr Val = attribute111
2 : 1 : Node Name = Node14 Node Type = node_element Node Val = <blank> Attr Name = attr141 Attr Val = attribute141
2 : 2 : Node Name = Node14 Node Type = node_element Node Val = <blank> Attr Name = attr142 Attr Val = attribute142
2 : 3 : Node Name = Node14 Node Type = node_element Node Val = <blank> Attr Name = attr143 Attr Val = attribute143
2 : 4 : Node Name = Node14 Node Type = node_element Node Val = <blank> Attr Name = attr144 Attr Val = attribute144
Любой пустой узел и любой узел без каких-либо явных атрибутов, кажется, теряются. Я вывел параметр parse_full load_file. Должно быть, я неправильно понимаю что-то очень основное.
Хотя я не уверен, что понимаю, что вы пытаетесь сделать, вы только печатаете строки в этом цикле:
for ( pugi::xml_attribute attr = nodeIn.first_attribute() ; attr ; attr = attr.next_attribute() )
Этот цикл выполняется только в том случае, если узел имеет один или несколько атрибутов, поэтому имеет смысл, что вы не видите никакого вывода для узлов без атрибутов.