GithubHelp home page GithubHelp logo

leethomason / tinyxml2 Goto Github PK

View Code? Open in Web Editor NEW
4.9K 227.0 1.8K 3.4 MB

TinyXML2 is a simple, small, efficient, C++ XML parser that can be easily integrated into other programs.

License: zlib License

CMake 2.21% Makefile 0.74% C++ 94.42% Python 1.39% Meson 1.24%

tinyxml2's Introduction

TinyXML-2

Test

TinyXML-2 is a simple, small, efficient, C++ XML parser that can be easily integrated into other programs.

The master is hosted on github: https://github.com/leethomason/tinyxml2

The online HTML version of these docs: http://leethomason.github.io/tinyxml2/

Examples are in the "related pages" tab of the HTML docs.

What it does.

In brief, TinyXML-2 parses an XML document, and builds from that a Document Object Model (DOM) that can be read, modified, and saved.

XML stands for "eXtensible Markup Language." It is a general purpose human and machine readable markup language to describe arbitrary data. All those random file formats created to store application data can all be replaced with XML. One parser for everything.

http://en.wikipedia.org/wiki/XML

There are different ways to access and interact with XML data. TinyXML-2 uses a Document Object Model (DOM), meaning the XML data is parsed into a C++ objects that can be browsed and manipulated, and then written to disk or another output stream. You can also construct an XML document from scratch with C++ objects and write this to disk or another output stream. You can even use TinyXML-2 to stream XML programmatically from code without creating a document first.

TinyXML-2 is designed to be easy and fast to learn. It is one header and one cpp file. Simply add these to your project and off you go. There is an example file - xmltest.cpp - to get you started.

TinyXML-2 is released under the ZLib license, so you can use it in open source or commercial code. The details of the license are at the top of every source file.

TinyXML-2 attempts to be a flexible parser, but with truly correct and compliant XML output. TinyXML-2 should compile on any reasonably C++ compliant system. It does not rely on exceptions, RTTI, or the STL.

What it doesn't do.

TinyXML-2 doesn't parse or use DTDs (Document Type Definitions) or XSLs (eXtensible Stylesheet Language.) There are other parsers out there that are much more fully featured. But they are generally bigger and more difficult to use. If you are working with browsers or have more complete XML needs, TinyXML-2 is not the parser for you.

TinyXML-1 vs. TinyXML-2

TinyXML-2 long been the focus of all development. It is well tested and should be used instead of TinyXML-1.

TinyXML-2 uses a similar API to TinyXML-1 and the same rich test cases. But the implementation of the parser is completely re-written to make it more appropriate for use in a game. It uses less memory, is faster, and uses far fewer memory allocations.

TinyXML-2 has no requirement or support for STL.

Features

Code Page

TinyXML-2 uses UTF-8 exclusively when interpreting XML. All XML is assumed to be UTF-8.

Filenames for loading / saving are passed unchanged to the underlying OS.

Memory Model

An XMLDocument is a C++ object like any other, that can be on the stack, or new'd and deleted on the heap.

However, any sub-node of the Document, XMLElement, XMLText, etc, can only be created by calling the appropriate XMLDocument::NewElement, NewText, etc. method. Although you have pointers to these objects, they are still owned by the Document. When the Document is deleted, so are all the nodes it contains.

White Space

Whitespace Preservation (default, PRESERVE_WHITESPACE)

Microsoft has an excellent article on white space: http://msdn.microsoft.com/en-us/library/ms256097.aspx

By default, TinyXML-2 preserves white space in a (hopefully) sane way that is almost compliant with the spec. (TinyXML-1 used a completely different model, much more similar to 'collapse', below.)

As a first step, all newlines / carriage-returns / line-feeds are normalized to a line-feed character, as required by the XML spec.

White space in text is preserved. For example:

<element> Hello,  World</element>

The leading space before the "Hello" and the double space after the comma are preserved. Line-feeds are preserved, as in this example:

<element> Hello again,
          World</element>

However, white space between elements is not preserved. Although not strictly compliant, tracking and reporting inter-element space is awkward, and not normally valuable. TinyXML-2 sees these as the same XML:

<document>
	<data>1</data>
	<data>2</data>
	<data>3</data>
</document>

<document><data>1</data><data>2</data><data>3</data></document>

Whitespace Collapse (COLLAPSE_WHITESPACE)

For some applications, it is preferable to collapse whitespace. Collapsing whitespace gives you "HTML-like" behavior, which is sometimes more suitable for hand typed documents.

TinyXML-2 supports this with the 'whitespace' parameter to the XMLDocument constructor. (The default is to preserve whitespace, as described above.)

However, you may also use COLLAPSE_WHITESPACE, which will:

  • Remove leading and trailing whitespace
  • Convert newlines and line-feeds into a space character
  • Collapse a run of any number of space characters into a single space character

Note that (currently) there is a performance impact for using COLLAPSE_WHITESPACE. It essentially causes the XML to be parsed twice.

Pedantic Whitespace (PEDANTIC_WHITESPACE)

For applications that need to know about text nodes that are composed entirely of whitespace, PEDANTIC_WHITESPACE is available. PEDANTIC_WHITESPACE maintains all the whilespace between elements.

PEDANTIC_WHITESPACE is a new mode and not as tested as the other whitespace modes.

Error Reporting

TinyXML-2 reports the line number of any errors in an XML document that cannot be parsed correctly. In addition, all nodes (elements, declarations, text, comments etc.) and attributes have a line number recorded as they are parsed. This allows an application that performs additional validation of the parsed XML document (e.g. application-implemented DTD validation) to report line number information for error messages.

Entities

TinyXML-2 recognizes the pre-defined "character entities", meaning special characters. Namely:

&amp;	&
&lt;	<
&gt;	>
&quot;	"
&apos;	'

These are recognized when the XML document is read, and translated to their UTF-8 equivalents. For instance, text with the XML of:

Far &amp; Away

will have the Value() of "Far & Away" when queried from the XMLText object, and will be written back to the XML stream/file as an ampersand.

Additionally, any character can be specified by its Unicode code point: The syntax &#xA0; or &#160; are both to the non-breaking space character. This is called a 'numeric character reference'. Any numeric character reference that isn't one of the special entities above, will be read, but written as a regular code point. The output is correct, but the entity syntax isn't preserved.

Printing

Print to file

You can directly use the convenience function:

XMLDocument doc;
...
doc.SaveFile( "foo.xml" );

Or the XMLPrinter class:

XMLPrinter printer( fp );
doc.Print( &printer );

Print to memory

Printing to memory is supported by the XMLPrinter.

XMLPrinter printer;
doc.Print( &printer );
// printer.CStr() has a const char* to the XML

Print without an XMLDocument

When loading, an XML parser is very useful. However, sometimes when saving, it just gets in the way. The code is often set up for streaming, and constructing the DOM is just overhead.

The Printer supports the streaming case. The following code prints out a trivially simple XML file without ever creating an XML document.

XMLPrinter printer( fp );
printer.OpenElement( "foo" );
printer.PushAttribute( "foo", "bar" );
printer.CloseElement();

Examples

Load and parse an XML file.

/* ------ Example 1: Load and parse an XML file. ---- */
{
	XMLDocument doc;
	doc.LoadFile( "dream.xml" );
}

Lookup information.

/* ------ Example 2: Lookup information. ---- */
{
	XMLDocument doc;
	doc.LoadFile( "dream.xml" );

	// Structure of the XML file:
	// - Element "PLAY"      the root Element, which is the
	//                       FirstChildElement of the Document
	// - - Element "TITLE"   child of the root PLAY Element
	// - - - Text            child of the TITLE Element

	// Navigate to the title, using the convenience function,
	// with a dangerous lack of error checking.
	const char* title = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->GetText();
	printf( "Name of play (1): %s\n", title );

	// Text is just another Node to TinyXML-2. The more
	// general way to get to the XMLText:
	XMLText* textNode = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->FirstChild()->ToText();
	title = textNode->Value();
	printf( "Name of play (2): %s\n", title );
}

Using and Installing

There are 2 files in TinyXML-2:

  • tinyxml2.cpp
  • tinyxml2.h

And additionally a test file:

  • xmltest.cpp

Generally speaking, the intent is that you simply include the tinyxml2.cpp and tinyxml2.h files in your project and build with your other source code.

There is also a CMake build included. CMake is the general build for TinyXML-2.

(Additional build systems are costly to maintain, and tend to bit-rot. They are being removed over time.)

Building TinyXML-2 - Using vcpkg

You can download and install TinyXML-2 using the vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install tinyxml2

The TinyXML-2 port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Versioning

TinyXML-2 uses semantic versioning. http://semver.org/ Releases are now tagged in github.

Note that the major version will (probably) change fairly rapidly. API changes are fairly common.

License

TinyXML-2 is released under the zlib license:

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

Contributors

Thanks very much to everyone who sends suggestions, bugs, ideas, and encouragement. It all helps, and makes this project fun.

The original TinyXML-1 has many contributors, who all deserve thanks in shaping what is a very successful library. Extra thanks to Yves Berquin and Andrew Ellerton who were key contributors.

TinyXML-2 grew from that effort. Lee Thomason is the original author of TinyXML-2 (and TinyXML-1) but TinyXML-2 has been and is being improved by many contributors.

Thanks to John Mackay at http://john.mackay.rosalilastudio.com for the TinyXML-2 logo!

tinyxml2's People

Contributors

a-lunkov avatar alanscut avatar amai2012 avatar brad-anderson avatar chocobo1 avatar cugone avatar dennisjenkins75 avatar dmitry-me avatar gamaral avatar hyperair avatar jasjuang avatar jayxon avatar jeromemartinez avatar jsenn avatar jurajx avatar jwittner avatar kainjow avatar kezenator avatar kinddragon avatar leethomason avatar lsolanka avatar numatrumpet avatar offlinemark avatar orbitcowboy avatar pkeus avatar pzychotic avatar sirr4t avatar sniperbat avatar thezoc avatar uliwitness avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinyxml2's Issues

XMLDocument destructor crashes in DEBUG build

XMLDocument destructor crashes in DEBUG build (due to assert check):
Assertion failed: (_commentPool.CurrentAllocs() == 0), function ~XMLDocument, file tinyxml2.cpp, line 1511.
Abort trap: 6

I'm guessing that it may be somehow related to the end-of-line character encoding in XML file.

The tinyxml2 project code was build on the latest version of OSX 10.8. Here are the code and data files to reproduce the issue:
https://dl.dropbox.com/u/9763817/test-crash.tar.gz

name conflict/ vs 2010, c++

Sorry, noob problem.

Building a 64 bit C++ app.
VS returns;

tinyxml2.cpp(372): error C2872: 'XMLDocument' : ambiguous symbol
1> could be 'c:\program files (x86)\microsoft sdks\windows\v7.0a\include\msxml.h(273) : XMLDocument'
1> or 'c:\navidentdata\navident\navident\tinyxml2.h(986) : tinyxml2::XMLDocument'

is there a way to have it ignore msxml?

TIA.

Saving in UTF-8

Hello!
TinyXML-2 supports UTF-8, but how to save programatically created document in UTF-8 encoding?

"Moving" a subtree to a new document...

I am trying to convert a large codebase from using tinyxml to tinyxml2.

In the original code it moves a subtree from one document to another via this way:

Parent->LinkRemoveChild(Element);
NewDoc->LinkEndChild(Element);

but with tinyxml2 it 'controls' the memory model so LinkRemoveChild() no longer exists.

Do you have any suggestions on how to 'move/transfer' a subtree of nodes from one document to another efficiently? ie. Least amount of code futz and smallest amount of memory allocation?

Do I need to use the Visitor pattern now somehow?

xmltest fails

On line 196, trying to access null pointer

First-chance exception at 0x00d5d55c in tinyxml2.exe: 0xC0000005: Access violation reading location 0x00000000.

Compilation error on Fedora 16

Issue:
ptrdiff_t was not declared in tinyxml2.cpp on line 319
Makefile in tinyxml2 would not build.
My project would not build because of the same error, I added the header and the .cpp file into my sources.

I cloned my copy of TinyXml2 from the repo today, 14 May 2012. Small issue, but never the less something worth mentioning.

Fix:
change line 319 in tinyxml2.cpp from
ptrdiff_t delta = 0;
to
std::ptrdiff_t delta = 0;

Error message:
[### tinyxml2]$ make
g++ xmltest.cpp tinyxml2.cpp tinyxml2.h -o xmltest
tinyxml2.cpp: In static member function ‘static const char* tinyxml2::XMLUtil::GetCharacterRef(const char_, char_, int_)’:
tinyxml2.cpp:319:3: error: ‘ptrdiff_t’ was not declared in this scope
tinyxml2.cpp:319:3: note: suggested alternative:
/usr/lib/gcc/x86_64-redhat-linux/4.6.3/../../../../include/c++/4.6.3/x86_64-redhat-linux/bits/c++config.h:1738:28: note: ‘std::ptrdiff_t’
tinyxml2.cpp:319:13: error: expected ‘;’ before ‘delta’
tinyxml2.cpp:332:4: error: ‘delta’ was not declared in this scope
tinyxml2.cpp:359:4: error: ‘delta’ was not declared in this scope
tinyxml2.cpp:374:14: error: ‘delta’ was not declared in this scope
make: *_* [xmltest] Error 1

A typo about FirstChildElement() & LastChildElement() ?

Hi,

I've noticed that while inside XMLNode::FirstChildElement() & XMLNode::LastChildElement() functions
at the string matching level you're using the Name() function of XMLElement (and so a conversion with ToElement()),
inside XMLNode::NextSiblingElement() & XMLNode::PreviousSiblingElement() you're using the Value() function of XMLNode directly. Indeed, Name() function of XMLElement is just a call to Value() function of XMLNode and Value() is not a virtual functions, that is a potential overrideable function.
What do you think?
could we assume Value() instead of Name() inside XMLNode::FirstChildElement() & XMLNode::LastChildElement() avoiding the ToElement() function call?

Let me know if it is unclear,
Thanks

cppcheck issues

cppcheck gives following output on tinyxml2 1.0.5:

[tinyxml2.cpp:691]: (style) C-style pointer casting
[tinyxml2.cpp:193]: (style) The scope of the variable 'i' can be reduced
[tinyxml2.cpp:1630]: (style) The scope of the variable 'bom' can be reduced
[tinyxml2.h:576]: (style) 'XMLNode::operator=' should return 'XMLNode &'.
[tinyxml2.h:630]: (style) 'XMLText::operator=' should return 'XMLText &'.
[tinyxml2.h:655]: (style) 'XMLComment::operator=' should return 'XMLComment &'.
[tinyxml2.h:689]: (style) 'XMLDeclaration::operator=' should return 'XMLDeclaration &'.
[tinyxml2.h:717]: (style) 'XMLUnknown::operator=' should return 'XMLUnknown &'.
[tinyxml2.h:1215]: (style) 'XMLHandle::operator=' should return 'XMLHandle &'.
[tinyxml2.h:1261]: (style) 'XMLConstHandle::operator=' should return 'XMLConstHandle &'.
[tinyxml2.h:1110]: (style, inconclusive) Technically the member function 'tinyxml2::XMLDocument::DeleteNode' can be const.

Compiling under GNU/Linux not possible

Hello,
I tried to compile tinyxml2 with archlinux with the standard g++ (GCC) 4.6.2 20120120 (prerelease)
but I get the error that ptrdiff_t was not declared in this scope.
I changed some headers from old c-headers to the modern c++ headers (I think you recommend the use of g++ anyway because everywhere in your code you are using g++ instead of gcc - so it should be ok?).
I think especially including fixes the problem (memory.h seems not to be needed) - it compiles with this change and it seems to have no side effects for my example xml.
Only adding <stddef.h> (old c-header) works too.

Compiler call and error output: http://pastebin.com/5CCxY40B
Patch for tinyxml2.h: http://pastebin.com/9r2WBG3u

The .cpp-headers should possibly changed too?

unclosed quote attribute crash

Xml attribute with invalid quotes will cause a crash the application, for example:

[ipxml ws="1"][info bla=" /][/ipxml]

(the bla attribute has an unterminated quote)
(change brackets into chevrons)

XMLDocument::Clear ?

XMLDocument now doesn't have a Clear method (as in tinyxml), so one has to destroy the object and re-create new instance to continue working with that variable. Am I wrong?

Thanks.

Row/column of current element / error?

In TinyXML1 it was possible to query the row/column of the currrent element (e.g. in case of an error). This was very nice to show a descriptive error message so the user was able to pinpoint the error easily. Even it was possible to open an editor and jumping to that element.

I see that in TinyXML2 the Row() and Column() methods are gone. Will the return or is there an alternative / better way to obtain that information?

Note that the error must not be an XML error, but may come from a user-defined validation. So the element might be XML correct, but the content may be wrong for the application.

XMLDocument::Parse method is not safe

As XMLDocument::Parse accept just one parameter "const char * xml", it is not safe for just use "strlen" to get the xml buffer size inside. If the xml is not end with "/0" for any reason, the parse will fail.For example, I got the error code XML_ERROR_PARSING_TEXT.
I think , add one more parameter, for example "unsigned long size" , explicit indicate the size of xml buffer is better.

Question: How do you export an XMLElement to an XML string in TinyXML2

0 down vote favorite

In TinyXml 1 it was possible to convert a child element to a string using the << operator, e.g.

TiXmlElement * pxmlChild = pxmlParent->FirstChildElement( "child" );
std::stringstream ss;
ss << (*pxmlChild);

This doesn't appear possible in TinyXml2. How do you convert an element to an xml string in TinyXml2?

e.g. if the xml was:

<parent>
    <child>
        <value>abc</value>
    </child>
<parent>

and I'm at the child element I want the xml for that element, e.g.

<child>
    <value>abc</value>
</child>

XMLDocument::SaveFile crashes if fopen fails

Unlike XMLDocument::LoadFile, it doesn't check to make sure the file pointer is valid.

(On a related note, it'd be nice if SaveFile returned an error code like LoadFile and had a version that took a file pointer as input.)

Infinite Loop in XMLElement::ShallowEqual(...)

In the attribute comparison loop, attribute pointers are not advanced, thus resulting in an infinite loop when calling :ShallowEqual with Nodes that both contain Attributes.
Should IMHO read:

....line 1241, tinyxml2.cpp

    while ( a && b ) {
     if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {
        return false;
     }
      a = a->Next();
      b = b->Next(); 
    }

Unable to Overload the new operator in the Block* block = new Block(); functions

Due to performance & memory issue present in the previous tinyxml version i have ported the new tinyxml2 for our purpose.

We got good improvement in performance level when compared with previous tinyxml. Also i need to measure the memory requirement for writing & parsing the XML data using the tinyxml2. because I have used tinyxml2 to write the large amount (more than 9MB) of data in xml format.

So I decided to overload the "new" operators in xml classes to find how much memory occupied for xml data's.

But i am unable to overload the "new" operator to share memory from own memory area instead of heap memory.

Please help me, how can i overload the "new" operator for this below case to share memory from own memory area.

Also, how can i found out memory leak incaseof memory from heap.

template< int SIZE >
class MemPoolT : public MemPool
{
public:
MemPoolT() : root(0), currentAllocs(0), nAllocs(0), maxAllocs(0) {}
~MemPoolT() {
// Delete the blocks.
for( int i=0; i<blockPtrs.Size(); ++i ) {
delete blockPtrs[i];
}
}

virtual void* Alloc() {
    if ( !root ) {
         // Need a new block.
         Block* block = new Block();
         blockPtrs.Push( block );

         for( int i=0; i<COUNT-1; ++i ) {
             block->chunk[i].next = &block->chunk[i+1];
        }
         block->chunk[COUNT-1].next = 0;
         root = block->chunk;
    }
    void* result = root;
    root = root->next;

    ++currentAllocs;
    if ( currentAllocs > maxAllocs ) maxAllocs = currentAllocs;
    nAllocs++;
    return result;
}
virtual void Free( void* mem ) {
    if ( !mem ) return;
    --currentAllocs;
    Chunk* chunk = (Chunk*)mem;
    memset( chunk, 0xfe, sizeof(Chunk) );
    chunk->next = root;
    root = chunk;
}

private:
    enum { COUNT = 1024/SIZE };
    union Chunk {
        Chunk* next;
        char mem[SIZE];
    };
    struct Block {
        Chunk chunk[COUNT];
    };
DynArray< Block*, 10 > blockPtrs;
Chunk* root;

int currentAllocs;
int nAllocs;
int maxAllocs;

};

memcpy and memset issues

Hello.

I add the tinyxml2 into my iOS project, compile with xcode, I got error just like this:
" Call to function 'memcpy' that is neither visible in the template definition nor found by argument-dependent lookup "

memset as same too.

And, I add " #include <string.h> " into tinyxml2.h , the error had gone, compile succeeded.
This modification is right here?

best regards.
sniperbat

Compactify float attributes output without losing of precision

If not using "%g" because of loss of precision, we still can add some simple code to compactify floats formatted with "%f".It can be done by cutting insignificant zeroes at the end,
so 2.0f will be printed as "2", not "2.000000"

void XMLUtil::ToStr( float v, char* buffer, int bufferSize )
{
    int len = TIXML_SNPRINTF( buffer, bufferSize, "%f", v );

#ifdef COMPACTIFY_FLOATS
    for (int i = len - 1; i > 0; --i) switch(buffer[i]) {
        case '0':
            buffer[i] = '\0';
            break;
        case '.':
            buffer[i] = '\0'; i = 0;
            break;
        default:
            i = 0;
    }
#endif
}

Missing check for some XML tag name starting chars

The code in StrPair::ParseName assumes that only alpha chars are allowed as the first character of an XML tag name, however this is not the case.
The XML spec (http://www.w3.org/TR/REC-xml/#NT-NameStartChar) says:

NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] Name ::= NameStartChar (NameChar)*

So I think the _ and : chars should be allowed by this check as well.

Also, thanks for tinyxml & tinyxml2, they are great libraries :)

Can't return XMLDocument object?

If I have a function like this:

XMLDocument getDoc(std::string file){
XMLDocument doc;
if(!doc.LoadFile(file.c_str())){
return XMLDocument();
}
return doc;
}

I get this error:
/tinyxml2/tinyxml2.h:1496:5: error: ‘tinyxml2::XMLDocument::XMLDocument(const tinyxml2::XMLDocument&)’ is private
file.cpp:4: error: within this context
/tinyxml2/tinyxml2.h:1496:5: error: ‘tinyxml2::XMLDocument::XMLDocument(const tinyxml2::XMLDocument&)’ is private
file.cpp:6: error: within this context

Can anyone explain what's going on there, please?

XMLDocument.Parse interface suggestion

XMLDocument.Parse(const char* xml)

can be replaced with

XMLDocument.Parse(const char* xml, size_t len = -1)

so it will also accept memory buffers without ending zero (e.g. data read from file).
As for now, user has to copy the data buffer to the newly allocated memory and manually add zero byte.

*edit: code corrected to be more safe, but still is not ideal

Can't find how to attach a code, so here it is:

int XMLDocument::Parse( const char* p, size_t len )
{
DeleteChildren();
InitDocument();

if ( !p || !*p || !len) {
    SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
    return errorID;
}

const char* orig = p;
p = XMLUtil::SkipWhiteSpace( p );
p = XMLUtil::ReadBOM( p, &writeBOM );
if ( !p || !*p ) {
    SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
    return errorID;
}

len = (len < 0) ? strlen( p ) : len - (p - orig);

if (len <= 0) {
    SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
    return errorID;
}

charBuffer = new char[ len+1 ];
memcpy( charBuffer, p, len );
charBuffer[len] = 0;

ParseDeep( charBuffer, 0 );
return errorID;

}

Generating XML string without formatting

I understand one can use XMLDocument::Print() and XMLPrinter::CStr() to generate a formatted XML string. Is it possible to generate a version of XML string that does not contain the pretty tabs and line breaks (i.e. the pretty formatting), except when it's part of the XML data?

delete statement in the DynArray destructor

Hi,

first of all, thanks for sharing TinyXML2.

I was giving a look at your code when my eyes saw the destructor of DynArray class template.
There you free the memory allocate via 'new TYPE[ SIZE ]' (TYPE & SIZE are just placeholders here),
and you free the memory using the 'delete' keyword.
Shouldn't you have used the 'delete [] array' instead?

Thanks

CMake?

Hi,

This is a feature request not a bug: have you considered using CMake?
It makes the project very portable...

Thanks,
Christophe

Best option to search?

Hi!
I've recently started using tinyxml2 for my project, and I'm using it to store a list of music files (Name of song, artist etc). I was wondering what the best method for retrieving a certain song info is. Would I have to do a linear search, or is binary or something more efficient possible? Please let me know if you need more information! Thank you!
Aamir

dicussion about examples

Lee,
I've read your comments and saw the code, it is really good. I opened this issue only to keep the discussion going. Because I don't see any other place suitable for this. If you have a better option, let me know.
Back to the examples, do you like the approach of putting the input xml as a string inside the example? If so, I can refactor some of my examples to reflect that. In some cases, it would be nice to use the dream.xml also.
What do you think?
BTW, great work! We are currently in the process of integrating tinyxml2 in our application, and I'm very happy for the time being.
Best regards,
Juan

spaces after = in attribute list fail with XML_ERROR_PARSING_ATTRIBUTE

Trying to use tinyXML2 to replace an old MSXML 4.0 parser in my app.

Seems to work good except that the XML I need to parse has spaces in our attribute values similar to the following:

----edit, everything in this post after this line is incorrect...read the rest of the thread to get the actual errror---
<element attribute1="Test Attribute"/>

Seems to foil the parser with it parsing 'Test' as the value and then trying to parse 'Attribute' as another name/value pair (which fails since there is no '=').

Am I missing a flag somewhere that tells the parser that there can be spaces in tags or is this a bug in the parser?

UTF-16 support

more and more project are requiring XML to be encoded with UTF-16;
do you plan to add the utf-16 support to tinyxml?

Documentation typo

Hi !

Your first example :

XMLDocument doc; ... doc.Save( "foo.xml" );

should be :

XMLDocument doc; ... doc.SaveFile( "foo.xml" );

Type conversion for text element

Attributes have a reasonable rich type conversion API. (QueryInt, Bool, etc.) An interesting request is to have this on text elements, or at least expose the utility through XMLUtil

Saving float/double attributes suggestion

Hi
Maybe it's a good idea to use "%g" format specifier in XMLUtil::ToStr() instead of "%f",
so, for example, PushAttribute("x", 2.0f) will print not x="2.000000" but x="2".
This way, saved files with a lot of float attributes can become more compact and human-readable.

MSVC - Static Code Analysis Warnings

File: tinyxml2.h
Lines: 366 & 367

These two lines cause warnings from the MSVC static code analysis - the simple fix is to explicitly cast the arguments to isspace() to unsigned char, which IIRC is correct usage of this function.

static const char* SkipWhiteSpace( const char* p ) { while( !IsUTF8Continuation(p) && isspace( *p ) ) { ++p; } return p; }
static char
SkipWhiteSpace( char* p ) { while( !IsUTF8Continuation(*p) && isspace( *p ) ) { ++p; } return p; }

Should be:

static const char* SkipWhiteSpace( const char* p ) { while( !IsUTF8Continuation(_p) && isspace( (unsigned char)_p ) ) { ++p; } return p; }
static char* SkipWhiteSpace( char* p ) { while( !IsUTF8Continuation(_p) && isspace( (unsigned char)_p ) ) { ++p; } return p; }

Great library which I've used several times - hope this is helpful.

Cheers.

Consistent Style

The coding style thing is making me a little insane. Not my own style, I'm fine with that. :) But incoming patches can't be diffed in, and valid changes from other code lines are stuck, because of incompatible style. Which is is silly.

Artistic Style is an auto-formatter that creates code reasonably close to my own style. (The only exception is where I do getters on one line, and it doesn't. But nothing is perfect.) By now setting forks to use the same style, I can do proper diffs.

Checkin coming, but I'll leave this as a note to what's going on.

Benchmark?

Hi I searched the net for a tinyxml2 benchmark.
Only the original version crops up. So I cant compare it to pugi etc.
Has anyone got a benchmark for the latest tinyxml2?

I'm just looking for some indication of speed for a game I'm making

Something bad while parsing XML file

Hi.
I'm a new user of tinyxml. First of all, I must say that you are creating an excellent product. And thank you for that. I've downloaded tinyxml2 and compiled it in C++ Builder (because I'm used to it and don't want to move to Visual Studio :) ). I've compiled .lib file from the first time (which seemed very surprisingly for me because I thought that I do something wrong until the last moment :) ) and put it to the builder's folder (where all other libraries are located). So next thing I do is that I've started to write the code. The library works fine while all tags in XML-file are not empty. For example, such XML file crashes tinyxml:

<?xml version="1.0" encoding="utf-8" ?>
<AutoBase>
    <Car>
        <Manufacturer>My car</Manufacturer>
        <Model>a</Model>
        <Configuration></Configuration>
        <Year>2012</Year>
        <Fueltype>2</Fueltype>
        <Odometer>0</Odometer>
        <Price>0</Price>
        <Color>a</Color>
        <Volume>4</Volume>
    </Car>
</AutoBase>

The error happens after I want to check the type of the Configuration tag.
The Builder's CodeGuard points that there is an error on line 685 in tinyxml.h:

int Type() const    { return type; }

And the message is:

Method called on invalid object in process: AutoCat.exe(1424)  - d:\program files\embarcadero\rad studio\9.0\include\windows\rtl\tinyxml.h#685
  Attempt to access 44 byte(s) at 0x00000000.

And here is the code that I use to load XML:

carList->clear(true);
TiXmlNode * pChild, * pChildParam;
TiXmlDocument doc( filename );
bool loadOkay = doc.LoadFile();
if(!loadOkay) return false;


for ( pChild = doc.RootElement()->FirstChild(); pChild != 0; pChild = pChild->NextSibling()){
    if(pChild->NoChildren()) continue;
    Car * CarNode = new Car();
    for ( pChildParam = pChild->FirstChild(); pChildParam != 0; pChildParam = pChildParam->NextSibling()){
        char * name = new char[strlen(pChildParam->Value()) + 1];
        strcpy(name, pChildParam->Value());
        if(pChildParam->FirstChild()->Type() != TiXmlNode::TINYXML_TEXT)
            continue;
        if(!stricmp(name, "manufacturer"))
            CarNode->manufacture = pChildParam->FirstChild()->ToText()->Value();
        else if(!stricmp(name, "model"))
            CarNode->model = pChildParam->FirstChild()->ToText()->Value();
        else if(!stricmp(name, "configuration"))
            CarNode->config = pChildParam->FirstChild()->ToText()->Value();
        else if(!stricmp(name, "year"))
            CarNode->year = StrToInt(pChildParam->FirstChild()->ToText()->Value());
......
        if(name)
            delete []name;
    }
    carList->insert(CarNode);
}
if(pChild) delete pChild;
if(pChildParam) delete pChildParam;

return true;

If there is something wrong with my code please tell me where I'm mistaken. I'm a beginner at C++ and sorry if something seems very stupid for you:) Also sorry for my poor English.
Best regards,
Alexander

Just some design/logic issues

Hi,

About your XmlNode:

  1. DeleteChildren() is called to deallocate the children of that node.
    But at that point isn't necessary to unlink each element before deleting it. After all you're going to remove all children and you wan't need the double linked list anymore. As it is now, It would cost an additional O( K*n ) time.
    What do you think?

  2. You can call an insert operation of XmlNode class and insert a new node inside that class. The node inserted will become a child of the first node(the parent). Wait, let's do an example since my English is not good:

(I know I cannot instantiate a XmlNode variable but let's just simplify a bit)

XmlNode * pB = new XmlNode();
XmlNode A;
A.InsertEndchild( pB );

A is the parent and B is its child.
InsertEndChild() will do the necessary stuff to link B inside the list of children of A.
Now, if you call DeleteChild( pB ), the function will just delete the node passed in.
And the unlink stuff? they will be done in the destructor of B, aftere delete all B's children.
So, when you use the Insert*() operations, the work about to link the child is done at the parent level, but when you
you call DelteChild() the unlink stuff is done the child level...
Shouldn't the link stuff be done at the prent level instead of child level?
Indeed:
2.1) In the descructor of B you call the parent UnLink() operation to unlink itsself.
2.2) The firstchild, lastChild, prev, next variables are used by the parent to mantain the double linked list of children.
(simply remove the unlink operation in the desctructor of XmlNode a put it inside the DeleteChild() function but before the delete call)
What do you think?

Let me know if it's unclear,
Thanks

GNU Windows

I can't use this lib under Codeblocks on Windows. I tried to change all references of _MSC_VER to _WIN32 but I'm having issues.
On compilation, It can't find accumulator, _TRUNCATE, vsnprintf_s.

Thx for help!

size of XMLtext?

Hi lee thanks for merging the update that I done.
Im working on cocos2dx atm which uses tiny xml for its windows 8 platform.

Here is a function in the code

bool XmlSaxHander::Visit( const XMLText& text )
{

//CCLog("Visit %s",text.Value());
CCSAXParser::textHandler(m_ccsaxParserImp, (const CC_XML_CHAR *)text.Value(), text.ValueTStr().size());
return true;

}

now my issue is tinyxml2 doesnt have a .ValueTStr().size() function.

Any hints?

Compilation errors while make

root@ubuntu:/home/user/dhara/TinyXML/leethomason-tinyxml2-8712757# make
g++ xmltest.cpp tinyxml2.cpp tinyxml2.h -o xmltest
xmltest.cpp: In function ‘int main(int, const char*)’:
xmltest.cpp:775: error: cast from ‘tinyxml2::XMLElement
’ to ‘int’ loses precision
xmltest.cpp:788: error: cast from ‘const tinyxml2::XMLElement_’ to ‘int’ loses precision
make: *_* [xmltest] Error 1

Errorcode enum name and strong type

Example: XMLDocument::Parse returns an int, not an enumeration type.
The error codes are in fact declared using an enum, but it is unnamed so I can't use that type name myself, either.
Besides declaring the various functions strongly to return the error code type (not some random integer value such as the number of nodes created), having the enum as a proper named type would let me map the error code to an exception in a standard way, using std::system_error (or boost's version as the case may be).
As low-hanging fruit with some benefit to users of the code, there is no reason not to give the enum containing XML_NO_ERROR etc. a declared name. Even without strengthening the return types of the functions that return error values yet, it would still be a useful step.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.