Skip to main content
gamedev.net
🔒 Locked

Tiny Xml

Started by magic_man Feb 18, 2009 at 8:08 AM 17 replies 5k views
Original Post
magic_man
magic_man
If I have a simple xml file such as

<?xml version="1.0"?>
<vector4>1.000000 0.000000 0.000000 0.000000</vector4>

Which consists of a list of four floating point values in a vector4 element, how do you extract the values from the element using TiXml? The documents do not seem to cover this issue and the code seems only able to convert to a string( GetText ), do I have to parse the string myself? Thanks
"You insulted me!" I did not say that in the private message Tom Sloper!
folcojp
folcojp
why dont you try something like




1.000000
1.000000
1.000000
1.000000


magic_man
magic_man
If what I am doing is not valid, or if this is a limitation of the library then I would consider using another library or changing the structure of the xml file. Yet I think it is valid and when checked against the scheme wrote for it, it is validated correctly. The previous xml file is just a snippet and the following is the relevant part of the xml and schema.

<?xml version="1.0"?>        <matrix16>         	<vector4>1.000000 0.000000 0.000000 0.000000</vector4>        	<vector4>0.000000 1.000000 0.000000 0.000000</vector4>        	<vector4>0.000000 0.000000 1.000000 0.000000</vector4>        	<vector4>0.000000 0.000000 0.000000 1.000000</vector4>        </matrix16>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" ><xsd:element name="matrix16" type="matrix16_type"/>	<xsd:simpleType name="float_list">		<xsd:list itemType="xsd:float"/>	</xsd:simpleType>		<xsd:simpleType name="vector4_type">		<xsd:restriction base="float_list">			<xsd:length value="4"/>		</xsd:restriction>	</xsd:simpleType>		<xsd:complexType name="matrix16_type">		<xsd:sequence>			<xsd:element name="vector4" type="vector4_type" minOccurs="4" maxOccurs="4"/>		</xsd:sequence>	</xsd:complexType>	</xsd:schema>
"You insulted me!" I did not say that in the private message Tom Sloper!
mrbastard
mrbastard
Quote:
Original post by magic_man
do I have to parse the string myself?


Yes, as XML specifies that the innermost content of a tag is CDATA - character data in an arbitrary format. Essentially that space is reserved for unformatted data like free text. There's no reason you can't put your data there, but you may as well use the structure of XML to your advantage.

Another alternative to folcojp's suggestion would be to use element attributes:

[size="1"]
magic_man
magic_man
Ok I see. Yet this seems to fly in the face of what schema primer does
for example
<listOfMyInt>20003 15037 95977 95945</listOfMyInt>
"You insulted me!" I did not say that in the private message Tom Sloper!
magic_man
magic_man
If I make the vector an attribute of the element as shown on msdn would there be any advantage to my original post, or would I still need to parse it myself?
Thanks
"You insulted me!" I did not say that in the private message Tom Sloper!
mrbastard
mrbastard
Yes, TinyXML will parse it. That's why I suggested it!

use TiXmlElement::Query*Attribute
[size="1"]
magic_man
magic_man
Quote:
Original post by mrbastard
Yes, TinyXML will parse it. That's why I suggested it!

use TiXmlElement::Query*Attribute

Are we on the same page here?
Is not what you suggested and what I asked two different things?
Quote:

and
Quote:


"You insulted me!" I did not say that in the private message Tom Sloper!
Christian Stieber
Christian Stieber
TinyXML will never parse the actual content strings, with the exception of getting certain attribute types parsed. As far as attributes go, you can get the strings as usual, or use a convenience method to get a float --- but it will never give you an array of floats.

As a side note, none of the XML libraries I've used so far offered string parsing like that. But then again, I prefer stuff that's lightweight or part of the operating system.

In my opinion, using "1 2 3 4" isn't particulary xml-ish: you're basically organizing the data outside the xml. Instead of parsing a string yourself, consider using xml instead as suggested.
magic_man
magic_man
So it seems that the general consensus is that you should not use xml lists and also not do it as the schema primer suggests?
Quote:
In my opinion, using "1 2 3 4" isn't particulary xml-ish: you're basically organizing the data outside the xml. Instead of parsing a string yourself, consider using xml instead as suggested.

I do not understand this. It is a list which is xml-ish and the organisation/validation is done via a schema.

originally my xml files had elements like
Quote:


Which after reading the schema primer I changed to what you see.
"You insulted me!" I did not say that in the private message Tom Sloper!
magic_man
magic_man
Quote:
"why dont you try something like... " (attributes)

Quote:
Essentially that space is reserved for unformatted data like free text. There's no reason you can't put your data there, but you may as well use the structure of XML to your advantage.

Quote:
In my opinion, using "1 2 3 4" isn't particulary xml-ish

I must admit that the resistance to using data in elements a little confusing. The choice of when to use attributes and elements is not a new discussion and I can find articles such as Principles of XML design: When to use elements versus attributes which suggests it is a design decision which should be taken into consideration. If in this instance (vector4) such features should be used is debatable yet the biggest problem seems to be that I can not find a C or C++ xml library which has these features. There is SAXON which is a Java or .Net library yet not C, could anyone suggest a library which I could use or do developers really not use these features in games when creating documents and editors?
Thanks
"You insulted me!" I did not say that in the private message Tom Sloper!
mrbastard
mrbastard
Quote:
Original post by magic_man
Are we on the same page here?


It seems not. I admit I didn't read the msdn article you linked to. Apologies.

Still, I can't see what you stand to gain by using space separated lists, whether inside CDATA or attribute values.

Maybe if you outline your reasons for preferring the lists?

I think the reason no c/c++ xml lib supports this is that if you use it as you suggest it's trivial to parse yourself. They are afterall meant to parse XML, not space separated lists.

[size="1"]
evolutional
evolutional
I just thought I'd point out that TinyXml is designed to be lightweight and fast and so doesn't do certain things such as Schema validation, etc. It's very likely that you'll have to manually read in the element yourself and parse it because TinyXml doesn't parse or validate what's inside the elements. You might want to look at another Xml processing library, such as libxml or so on.
swiftcoder
swiftcoder
Quote:
Original post by magic_man
or do developers really not use these features in games when creating documents and editors?
To be honest, I find XML to be far more trouble that it is worth. JSON is easier to parse, is far less verbose, and doesn't need schemas. It also has native support for lightweight arrays, pretty much analogous to what you are trying to do with CDATA.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
noe
noe
Quote:
Original post by swiftcoder
Quote:
Original post by magic_man
or do developers really not use these features in games when creating documents and editors?
To be honest, I find XML to be far more trouble that it is worth. JSON is easier to parse, is far less verbose, and doesn't need schemas. It also has native support for lightweight arrays, pretty much analogous to what you are trying to do with CDATA.


I don't really like XML too (after a while using it), is there anything else you can recommend besides JSON (although it looks very nice)?

Kylotan
Kylotan
YAML?

I do find it a bit odd that the XML specification contains provision for lists within an elements when there is a perfectly good representation available via a list of elements (ie. sibling nodes under a parent).

But either way, TinyXML doesn't parse that and probably never will. I think the answer to "do developers really not use this feature" is no - I don't think many people miss the absence of automatic parsing to a list, simply because it's so easy to do it the other ways.

But hey, if someone really wants to do this, perhaps something like the following will work:

std::copy(std::istream_iterator<int>(std::istringstream(myTXElement->GetText())), std::istream_iterator<int>(), std::back_inserter(myVectorOfInt));
swiftcoder
swiftcoder
Quote:
Original post by Kylotan
YAML?
Interesting, I hadn't run into YAML before. It fixes my main gripe with JSON (backslash-escapes required for newlines in strings), at the expense of considerable complexity.
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
nullsquared
nullsquared
I recommend Google Protocol Buffers

math.proto
package math;message vector4{    optional float x = 1;    optional float y = 2;    optional float z = 3;    optional float w = 4;}message matrix16{    repeated vector4 columns = 1;}


.cpp
#include "math.pb.h" // compiled by google's protocol buffervoid foo(){    math::vector4 vec;    vec.set_x(1);    vec.set_y(2);    vec.set_z(3);    vec.set_w(4);    std::ofstream out("data.dat");    vec.SerializeToOstream(&out);}void bar(){    std::ifstream in("data.dat");    math::vector4 vec;    vec.ParseFromIstream(∈);        assert(v.x() == 1);    assert(v.y() == 2);    assert(v.z() == 3);    assert(v.w() == 4);}


Everything is preprocessed so you load/save XML-style, except completely type-safe, no conversions to/from strings. No nodes and stuff, either. An optimized binary format with a generate interface for you.

Only problem is that the format is not human-editable. Meaning, you can edit .xml by hand, but you can't edit the output of protocol buffers by hand. But when it comes to vectors and matrices, I'm pretty sure you won't be writing anything by hand.
LorenzoGatti
LorenzoGatti
Quote:
Original post by evolutional
I just thought I'd point out that TinyXml is designed to be lightweight and fast and so doesn't do certain things such as Schema validation, etc. It's very likely that you'll have to manually read in the element yourself and parse it because TinyXml doesn't parse or validate what's inside the elements. You might want to look at another Xml processing library, such as libxml or so on.

This doesn't happen because TinyXML is "lightweight", it's a basic XML feature. The XML document structure stops at the vector4 element, and schema validation stops at checking that vector4's text content is a list of 4 floats; parsing or rebuilding that text node is the application's responsibility. In any language, splitting the string on space characters and parsing the floats isn't particularly difficult.

From the point of view of generic XML libraries, which need to deal with the full generality of XSD rather than with "obvious" cases like this one, the four float values nested inside vector4 have no name, reliably separating and recombining them is a huge can of worms, and there is no reason to assume that the user wants to look inside such complicated XSD types instead of treating the text or attribute value as a string.

Omae Wa Mou Shindeiru

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.