Download

XmlParser can't parse beyond first Child.

Hi guys,

I have been trying to use XmlParser to parse a basic xml file ,e.g.



<list  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../XSD/MyXSD.xsd">
  <item id="1" name="ababa">
    <set name="test1" val="400"/>
    <set name="test3" val="500" />
    <set name="test6" val="true" />
    <set name="icon" val="icon.0828" />
  </item>
  <item id="2" name="random">
    <set name="test1" val="400"/>
    <set name="test56" val="20" />
    <set name="test6" val="false" />
    <set name="icon" val="icon.0828" />
  </item>
</list>


Which should be pretty straightforward, however XmlParser seems to be somewhat limited - at least, in terms of the functions we can access thus making the control very limited. Thing is, I’ve tried a lot of stuff, but maximum I can do, is for it to return the two tags, but never its children. Since there can be various children - and nested children as well - GetNextNode() is the way to go. However, this doesn’t seem to work properly as it always crashes the editor.

This way only finds the two tags:


if (rootNode->GetChildrenNodes().Num() > 0)
	{
		FXmlNode* childNode;
		int i = 1;
		for (auto child = rootNode->GetChildrenNodes().CreateConstIterator(); child; ++child)
		{
			childNode = *child;

			if (!childNode)
				continue;

                        if(GEngine)
			 GEngine->AddOnScreenDebugMessage(i, 2.0f, FColor::Red, childNode->GetTag());
			i++;
		}
	}

This one - which should be better as it has GetNextNode(), just crashes the editor:



int i = 1;
	for (const FXmlNode* node = rootNode->GetNextNode(); rootNode ; node = rootNode->GetNextNode())
	{
		if (GEngine)
			GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Red, node->GetTag());
		i++;
		
                // Sounds ridiculous but this would keep going up (i++) until infinity, had to include a manual stop for testing purposes, it seems XmlParser can't find the end of
               // the XML Nodes and just keeps on moving eternally and not let the launcher get past beyond 72% loading
		if (i > 80)  
			break;
	}


Any help? Has someone used this parser before?

From my understanding, that is the intended behaviour. rootNode matches the item. This node only has two children … and … which are the two ChildrenNodes you get from GetChildrenNodes(). In order to access the ChildrenNodes of the elements you’d need to get the children from these two nodes (which already are child nodes themselves). Something like this should list the elements (WARNING: the following hasn’t seen a compiler with the exception of the stuff copied from your post):


]if (rootNode->GetChildrenNodes().Num() > 0)
	{
		FXmlNode* childNode;
		int i = 1;
		for (auto child = rootNode->GetChildrenNodes().CreateConstIterator(); child; ++child)
		{
			childNode = *child;

			if (!childNode)
				continue;

                        if(GEngine)
			 GEngine->AddOnScreenDebugMessage(i, 2.0f, FColor::Red, childNode->GetTag());
			i++;

			FXmlNode* SetNode;
			uint32 SetNodeNumber = 1;
			for (auto SetElement = childNode->GetChildrenNodes().CreateConstIterator(); SetElements; ++SetElements)
			{
				SetNode = *SetElement;

				if (!SetNode )
					continue;

                  	        if(GEngine)
					GEngine->AddOnScreenDebugMessage(SetNodeNumber, 2.0f, FColor::Red, SetNode->GetTag());

				SetNodeNumber++;
			}
		}
	}

Your condition in the for loop is incorrect. You’re checking whether the rootNode is valid instead of the current node.

P.S.: You shouldn’t use int, use one of the Unreal typedefs instead (like (u)int8/16/32/64).

Can’t believe I didn’t see that, that was incredibly dumb. Thanks, will try it later