VerySimpleXML 2.0 – a lightweight, cross-platform, one-unit XML reader/writer for Delphi 2010 – 10.1 Berlin
There are lot of possibilities if you’re in need to parse or write XML files:
- use TXMLDocument (the MS XML wrapper)
- or use a xml component like OmniXML, NativeXml, ADOM, SAX, libxml2, DIXml, fcl-XML, Fast XMLParser, SimpleXML, OXml, or VerySimpleXML 1.0
Now here comes another one: the updated VerySimpleXML 2.0 – a lightweight, cross-platform, one-unit XML reader/writer for Delphi 2010 – 10.1 Berlin targeting at Win32, Win64, iOS, MacOSX and Android. Use it for well-formed XML files (like configuration files, interprocess communication protocols, etc.).
VerySimpleXML 2.0 is still open sourced and open for anyone to participate in the further development.
What’s new in version 2.0?
- Support for these nodes types: ntElement (default node type), ntComment (comment nodes), ntDocType (Document Type Definition, but not parsed/evaluated), ntText (text only nodes), ntCData (CDATA sections), ntProcessingInstr (processing instructions)
- Windows 32 bit, Windows 64 bit, Mac OSX, iOS and Android compatible
- Support for headless xml files
- Reduced memory consumption
- Allows now processing of large xml files without line breaks
- Node content is now read exactly as found (including line breaks)
- Case sensitive/insensitve node and attribute name handling (use doCaseInsensitive option)
- Write UTF-8 files with or without BOM (doWriteBOM option)
- Support for attributes without values (single attribute type)
- Support for the Delphi “nextgen compiler” and weak references for ARC
- Added a lot of TXMLDocument compatible methods
- Support for parsing the ntProcessingInstr nodes (processing instructions)
- Support for Windows, Unix and even custom line breaks
- Improved fluent interfaces
What’s the difference between version 1.x and version 2.0?
a) Root and Header nodes
There is no XmlDoc.Root
element any more (it’s still there but hidden in the private declarations part) because it’s renamed to XmlDoc.DocumentElement
to be more TXMLDocument compatible and it’s not created by default now.
Old version 1.0
1 2 3 4 5 6 7 8 9 10 |
Xml := TXmlVerySimple.Create; Xml.Header.Attribute['encoding'] := 'utf-8'; Xml.Root.NodeName := 'books'; Node := Xml.Root.AddChild('book'); Node.Attribute['id'] := 'bk103'; Node.Text := 'A book'; Xml.SaveToFile('test.xml'); Xml.Free; |
New version 2.0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Xml := TXmlVerySimple.Create; // Create a new XmlDocument with default encoding "utf-8" //Xml.Encoding := 'utf-8'; // A more convinient way to change the encoding //Xml.Header.Attribute['encoding'] := 'utf-8'; // is still valid // Add a new child node, the first child node is the DocumentElement Xml.AddChild('books'); // Add a new book node to the document root Node := Xml.DocumentElement.AddChild('book'); Node.Attributes['id'] := 'bk103'; Node.Text := 'A book'; Xml.SaveToFile('test.xml'); Xml.Free; |
You may have noticed that Node.Attribute['someattrib']
is now renamed to Node.Attributes['someattrib']
as well.
The above example still works by using fluent interfaces:
1 2 3 4 5 6 |
Xml := TXmlVerySimple.Create; Xml.AddChild('books').AddChild('book').SetAttribute('id', 'bk103').Text := 'A book'; Xml.SaveToFile('test.xml'); Xml.Free; |
or even written as a one liner : -)
1 2 3 4 |
TXmlVerySimple.Create.AddChild('books').AddChild('book').SetAttribute('id', 'bk103'). SetText('A book').Document.SaveToFile('test.xml').Free; |
The next gen compiler hints “H2593: code has no effect”, so you may omit the last .Free
…
b) Last line break
As VerySimpleXML 2.0 operates now on read and write buffers instead of string lines, it omits the last line break of a xml file when written.
How to upgrade to version 2.0?
- Replace
VerySimpleXml.pas
with the newVerySimpleXml.pas
- Replace
Xml.Root.NodeName
assignments withXml.AddChild
- Replace
Node.Attribute[]
withNode.Attributes[]
Come on – yet another XML parser?
About 3 years ago I was in a need for parsing some xml files, so I’ve started using TXMLDocument. But because it was a little bit slow, I’ve decided to write my own very simple xml parser (hence the name) because I couldn’t find an easy to use, “unbloated” xml component. VerySimpleXML was done in about two afternoons – I’m good in writing parsers ; -) and is still used in a lot of projects. At the end of last year I’ve upgraded to Delphi XE5 and startet porting the xml parser to the next gen compiler. And added a lot more features – mainly support for different node types like comments and cdata. VerySimpleXML is not “feature-complete”, nor is it the fastest delphi xml parser found (but still faster than TXmlDocument) – it is just a small and simple parser for small and simple xml files. If you need something more versatile, I highly recommend OXml – The next generation XML library for Pascal written by Ondřej Pokorný (the same author who updated and bug fixed the great OmniXML component) which even runs with Delphi 6 and FPC, Lazarus and C++Builder.
Found a bug or need help?
- Use the comment system below
- Use the google code issues list for reporting bugs or feature requests
- See Wiki:Help for documentation
- Take a look at the included examples
- Write me at dennis@spreendigital.de
33 Comments to VerySimpleXML 2.0 – a lightweight, cross-platform, one-unit XML reader/writer for Delphi 2010 – 10.1 Berlin
Well done! A really nice piece of sw.
October 23, 2014
Thank you for your bug reports!
November 1, 2014
program Example6 for xe6
error line:
// Process child nodes
for Child in Node.ChildNodes do
Walk(Writer, Indent, Child);
November 4, 2014
Thanks, Example 6 fixed
December 17, 2014
Waiting 3.0 implements DOM Vender
December 31, 2014
thanks for the feature proposal
March 18, 2015
Thank you.
March 20, 2015
What a sweet piece of code! Thanks so much.
On a regular basis, my application will “import” data from an XML file, massage it some, and move it into a few database tables.
Of all the XML parsers I tried, yours was the absolute easiest to use.
This isn’t necessary, of course, but if TXmlVerySimple fired an event each time a node was visited I could probably simplify my code even more. (If it already does, please forgive me for not studying your code.)
Best regards
April 16, 2015
What about a tool like the delphi xml wizard only better and cleaner? The acutal version of it isnt usable
April 17, 2015
How to add prefixes and namespaces?
July 9, 2015
Any chance to have this wonderful code ported over lazarus/free pascal?
Although a old Delphi practitioner, I am just a beginner in lazarus – it is above my skill level
Thank you
July 15, 2015
Any chace to include some Simple features?
Node prefixes and namespaces
On savefile, Empty nodes like
parameter to save xml in one single line
thanks 🙂
July 15, 2015
ups sorry for the request, I found the doCompact option
October 19, 2015
Hi,
How to install the VerySimpleXML in Delphi XE7?
Thanks.
October 20, 2015
@LucasB, you don’t need to “install” anything, just copy the VerySimpleXML.pas to your source directory (or adjust your search path settings) – see the included examples
February 5, 2016
Hi, i use you verysimpleXML, but it’s very slow when it write the file xml is it normal?
thanks
March 10, 2016
Nice piece of code, if a bit difficult for an old school pascal programmer to understand
If I use the .xml or .text property of the XML (so I can save in DB memo field) there is a ? processing character at the first position and most other XML parsers ignore the text. I remove this manually but is there a proper way?
May 19, 2016
Dennis, due to the code breaking change in DX 10.1 Berlin private variables are no more visible to class helpers so VerySimpleXML does not compile anymore.
I was very happy to find this cute XML component for android projects. Do you plan to revise the software for 10.1 and future delphi releases?
May 25, 2016
I’ll update it soon
May 24, 2016
UweH if your desperate and can not be bothered to work it out you could take a complete copy of TStreamreader and rename it to TMyStreamReader make the private variables public then change the places in xml.verysimple to use your new streamreader instead off delphi’s. The alternative would be to manipulate the stream (basestream) to mimic what Dennis was doing with it in the helper class.
May 26, 2016
Good news Dennis. Thanks in advance. I’m really looking forward.
May 26, 2016
here is just a fix hack accessing the private fields with the rtti, it is slow but should work. I need to completely rewrite the code, but in the meantime you may try this “beta”:
http://blog.spreendigital.de/wp-content/uploads/2016/05/Xml.VerySimple.2.0.2.beta_.zip
DONT USE THIS BETA, IT WON’T WORK WITH LARGE FILES! Please use the official v2.0.2
June 15, 2016
Please find current v2.0.2 at Github (see link on top), I’ve dropped the helper class and replaced it with an TXmlStreamreader class which gets the TStreamReader methods by RTTi in the constructor.
June 24, 2016
Hello Dennis:
At First. Thanks for the code. I am a c++ builder user. The 2.0.2 beta was work for c++ builder too. Thank you.
I’ve got a exception when I used
XmlObj->Text= Memo1->Text; ( Memo1->Text was xml type words. )
The Exception fired when the xml size is big. ( I forgot to count the size of it. )
My delphi was not good enough, so, maybe what i did was not the good way.
——— original ———-
procedure TXmlVerySimple.SetText(const Value: String);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create(”, TEncoding.UTF8);
try
Stream.WriteString(Value);
Stream.Position := 0;
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
———- modified ————-
procedure TXmlVerySimple.SetText(const Value: String);
var
Stream: TStringStream;
begin
Stream := TStringStream.Create(”, TEncoding.UTF8);
try
Stream.WriteString(Value);
Stream.Position := 0;
LoadFromStream(Stream,Stream.size+1); // <——– modified here
finally
Stream.Free;
end;
end;
June 24, 2016
Hello Dennis
I’v try the new v2.0.2 that you update few days ago on github.
The exception was not fired when SetText.
thank you.
June 24, 2016
what you did here is to set the buffer size larger than your input stream. the 2.0.2 beta tried to call the FillBuffer of the original TStream via RTTi if the stream hits the length but this RTTi call didn’t work (it returned NIL) because of not accessible private methods with 10.1 Berlin (see http://stackoverflow.com/questions/37874351/how-to-access-the-private-method-tstreamreader-fillbuffer-in-delphi-10-1-berlin) which I didn’t noticed. This was fixed in the 2.0.2 “not beta” – so don’t use the beta
😉
December 6, 2016
How do i can remove a node by index and save it
February 10, 2017
Hello Dennis,
Thanks for sharing this library. I have checked all the examples, writing to .xml is now clear for me. Do you may have examples to parse and process the content of an .xml file? It would be welcomed.
March 9, 2017
you should find all that in the examples 🙂
August 15, 2017
Do you have an example of how to delete nodes
this crashes upon saving
// onodes: TXmlNodeList;
onodes := oxml.PathNodes(C_audioformats);
if onodes nil then
begin
for I := onodes.Count-1 downto 0 do
onodes[i].Free;
end;
Thank you
August 15, 2017
Even this crashes
// onode: TXmlNode;
onode := oxml.PathNode(C_audioformats);
if (onode = nil) then
Exit(False);
pChildCount := onode.ChildNodes.Count;
if (pChildCount = 0) then
Exit(True);
onode.ChildNodes.Free;
August 15, 2017
remove node from parents childnodes, that should work – MyNode.Parent.ChildNodes.Remove(MyNode)
August 21, 2017
Excellent unit for XML parsing & great support from Dennis. Using VerySimpleXML I was able to finally migrate my mobile apps to Windows, Android & iOS (32\64-bit).
Leave a comment
About Dennis D. Spreen
Search
Recent Posts
- How to compile Lua 5.4.0 for Android as a dynamic library using Android Studio 4
- Please make inline vars usable for production – fix RSP-28892
- How to compile Lua 5.4.0 as a Mac OS X dynamic library
- How to compile Lua 5.4.0 for Linux as a shared library
- How to compile Lua 5.4.0 for Windows
- Daily Wage – a Spigot/Bukkit plugin that pays out a daily wage
- How to compile Lua 5.3.5 for Windows
- Better Collada exporter for Blender with custom properties
- MOS6502-delphi – a MOS 6502 CPU emulator for Delphi
- Pass a multidimensional array as a parameter (with a hidden caveat)
Categories
Tags
Archives
- May 2020
- March 2020
- June 2019
- March 2017
- August 2016
- July 2016
- June 2016
- January 2016
- September 2015
- February 2015
- January 2015
- October 2014
- September 2014
- August 2014
- May 2014
- March 2014
- February 2014
- November 2011
- June 2011
- February 2011
- March 2010
- September 2009
- August 2009
- July 2009
- May 2009
- March 2009
- February 2009
- January 2009
- November 2008
- October 2008
- February 2008
- June 2007
Delphi Feeds
- How To Live Track The ISS International Space Station December 20, 2024
- SmartInspect 4 Beta 1 Released December 20, 2024
- Mastering FastReport in Delphi: Dynamic File Reporting and Visualization December 19, 2024
- This was 2024 overview December 19, 2024
- Mon bilan GitHub pour l'année 2024 December 19, 2024
- Re-Architecting Legacy Applications: Top Software Transformation December 18, 2024
- The Horror of finding the right database! Part 3 December 18, 2024
- Using TeeChart in Vector Magnetics’ RivCross Software for Precise Directional Drilling December 18, 2024
- Upgrading C++Builder 12.2: Tip #7, bcc64x tips! December 17, 2024
- Enhancing Delphi Code Safety: Best practices, tools, and context December 17, 2024
October 13, 2014