• Advertisement
Sign in to follow this  

TinyXML2 query text if attribute matches

This topic is 2198 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

[color=#000000][font=Arial,]

I am trying to figure out a way to load the text from an XML document I have created using TinyXML2. Here is the entire document.
<?xml version=[color=#800000]"1.0" encoding=[color=#800000]"UTF-8"?>
[color=#800000]<map [color=#FF0000]version=[color=#0000FF]"1.0" [color=#FF0000]orientation=[color=#0000FF]"orthogonal" [color=#FF0000]width=[color=#0000FF]"15" [color=#FF0000]height=[color=#0000FF]"13" [color=#FF0000]tilewidth=[color=#0000FF]"32" [color=#FF0000]tileheight=[color=#0000FF]"32"[color=#800000]>
[color=#800000]<tileset [color=#FF0000]firstgid=[color=#0000FF]"1" [color=#FF0000]name=[color=#0000FF]"Background" [color=#FF0000]tilewidth=[color=#0000FF]"32" [color=#FF0000]tileheight=[color=#0000FF]"32"[color=#800000]>
[color=#800000]<image [color=#FF0000]source=[color=#0000FF]"background.png" [color=#FF0000]width=[color=#0000FF]"64" [color=#FF0000]height=[color=#0000FF]"32"[color=#800000]/>
[color=#800000]</tileset>
[color=#800000]<tileset [color=#FF0000]firstgid=[color=#0000FF]"3" [color=#FF0000]name=[color=#0000FF]"Block" [color=#FF0000]tilewidth=[color=#0000FF]"32" [color=#FF0000]tileheight=[color=#0000FF]"32"[color=#800000]>
[color=#800000]<image [color=#FF0000]source=[color=#0000FF]"block.png" [color=#FF0000]width=[color=#0000FF]"32" [color=#FF0000]height=[color=#0000FF]"32"[color=#800000]/>
[color=#800000]</tileset>
[color=#800000]<layer [color=#FF0000]name=[color=#0000FF]"Background" [color=#FF0000]width=[color=#0000FF]"15" [color=#FF0000]height=[color=#0000FF]"13"[color=#800000]>
[color=#800000]<data [color=#FF0000]encoding=[color=#0000FF]"base64"[color=#800000]>
AgAAAAIAAAACAAAA...
[color=#800000]</data>
[color=#800000]</layer>
[color=#800000]<layer [color=#FF0000]name=[color=#0000FF]"Block" [color=#FF0000]width=[color=#0000FF]"15" [color=#FF0000]height=[color=#0000FF]"13"[color=#800000]>
[color=#800000]<data [color=#FF0000]encoding=[color=#0000FF]"base64"[color=#800000]>
AwAAAAMAAAADAAAAAwAAAAM...
[color=#800000]</data>
[color=#800000]</layer>
[color=#800000]</map>

Basically, I want to copy the text from into a string called background only if the layer name is background.
I have gotten the other variables like so:
[color=gray]// Get the basic information about the level
version = doc.[color=#2B91AF]FirstChildElement([color=#800000]"map")->[color=#2B91AF]FloatAttribute([color=#800000]"version");
orientation = doc.[color=#2B91AF]FirstChildElement([color=#800000]"map")->[color=#2B91AF]Attribute([color=#800000]"orientation");
mapWidth = doc.[color=#2B91AF]FirstChildElement([color=#800000]"map")->[color=#2B91AF]IntAttribute([color=#800000]"width");
mapHeight = doc.[color=#2B91AF]FirstChildElement([color=#800000]"map")->[color=#2B91AF]IntAttribute([color=#800000]"height");

That works great because I know the element name and the attribute name. Is there a way to say get the doc.FirstChildElement("map")->FirstChildElement("layer") and if it = background, get the text.
How would I accomplish this. I want a way to differentiate between background, the texture tiles and block, the collision model.
Thanks!
[/font]

Share this post


Link to post
Share on other sites
Advertisement

A simple if statement should suffice:

name = doc.FirstChildElement("map")->FirstChildElement("layer");
if(name == "background")
{
// do stuff
}



Thanks for the reply. The part I am not getting is in the //do stuff code.

Here is essentially the process.

Two layers are needed: Background and Block (collision). I need to read in the data for each. The problem is that while I can verify that both layers exist, I need a way to read in the data to each specific string. For example, the code you provided will validate that the name is background but then to actually read in the text in the data tag. I feel like I am missing some sort of iterative component where I can see, "oh, this layer is called background?", now advance to the data element and read in the text. I also think if I was to say something like:

doc.FirstChildElement("map")->FirstChildElement("layer")->FirstChildElement("data")->GetText();

to obtain the data, when I query it again, it wouldn't return the Block data but again, the Background data. Basically, I am trying to figure out how to query specific text based on an attribute of an element.

If this layer is called Background, read the data element text into Background. if this layer is called Block, read the data element text into Block.

Am I going about this wrong?

Thank you again.

Share this post


Link to post
Share on other sites
Sounds like you want XPath support, which TinyXML doesn't seem to have. Google turned up this, however. But XPath may be overkill. Can't you just check the attribute names?

Share this post


Link to post
Share on other sites
Using XPath to navigate a trivial XML document is basically the same as trying to kill a mosquito by forcibly collapsing every dimension in the multiverse.

Overkill doesn't begin to describe it, IMHO ;-)


Just iterate over the elements, check the attribute, and you're done. A couple Google searches for TinyXML can turn up dozens of examples for how to walk an XML node tree.

Here's one possible approach:

TiXmlNode * child;
for(child = someNode->FirstChild(); child != NULL; child = child->NextSibling())
{
std::string nodename = child->Attribute("name");
if(nodename == "background")
{
// Load data into the background section
}
else if(nodename == "whatever")
{
// Load data into whatever other section
}
// etc.
}

Share this post


Link to post
Share on other sites
Thank you again ApochPiQ. I didn't realize node could be used to iterate/test for values. They way I was doing it worked for an XML where you knew exactly what was in it. Thank you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement