OXml - The next generation XML library for Pascal (Delphi, FPC, Lazarus)
Latest Version
2.15 (2024/01/03)
Basic info
OXml is a new XML library for Delphi and Lazarus, developed in late 2013. I took some inspiration from OmniXML but wrote the library completely from scratch.The aim of OXml is to be the most versatile and fastest XML library for the Pascal language.
OXml base features:
- XML DOM with XPath and namespace support
- sequential XML DOM parser
- XML SAX parser with class handlers for specific objects
- XML serializer (with and without enhanced RTTI)
- direct XML reader/writer
- vendor for Delphi's XmlIntf.TXMLDocument
- fast buffered text reader and writer with encoding support
- lots of useful helper classes like integer and string lists and dictionaries
- encoding support for pre-2009 Delphi
OJson extension features:
- JSON Tree ("DOM") with JSONPath support
- JSON Event ("SAX") parser with class handlers for specific objects
- direct JSON reader and writer with JSON serialization and deserialization
- RTTI serialization/deserialization of JSON objects
- JSON to XML conversion
OXml DataBinding extension features:
- Create object pascal binding to complex XSD documents.
- XSL transformation engine (XSLT).
OXml supports all Delphi versions starting from Delphi 5 on all platforms: Win32, Win64, OSX, iOS, Android, Linux.
OXml supports the latest Lazarus/FPC on all platforms (tested Win32, Win64, Linux, MacOSX).
OXml Features
Library design
- Use the same XML library for all your Pascal projects including:
- Delphi for Win32, Win64 and OSX (Delphi 5 and newer).
- Delphi ARC/NEXTGEN for iOS and Android (Delphi XE4 and newer).
- Delphi ARC/NEXTGEN for Linux (Delphi 10.2 and newer).
- Lazarus on Win32, Win64, Linux, OSX (Lazarus 1.0 and newer).
- Native pascal object oriented code.
- No external dll libraries are required.
- No dependency on a visual library like VCL, LCL or FMX.
- Full unicode support even for D5-D2007.
- Powerful XPath engine.
- Fast, powerful and easy-to-use namespace support for reading documents.
- Faster than everything else on all platforms thanks to various optimizations.
- OXml is able to read and write invalid XML documents and correct errors in them (if wanted). If not wanted, OXml throws an exception when you are trying to read/write an invalid XML document.
- Supports all on the platform available encodings (UTF-16, UTF-8, single-byte ISO, WIN, KOI8...) by all parsers automatically. That means that the encoding is read and set from the <?xml encoding="" ?> tag during both reading and writing.
Readers and writers included in OXml
OXml features 7 classes/units for working with XML documents:- TXMLWriter (OXmlReadWrite.pas): Basic XML writer. All other classes use it.
Use it directly if performance is crucial for you. - TXMLReader (OXmlReadWrite.pas): Basic XML reader. All other classes use it.
Don't use it directly. If performance is crucial for you, use SAX which has the same performance but is much more comfortable to work with. - TSAXParser (OXmlSAX.pas): Event-based parser according to the SAX specification.
Anonymous methods are supported for modern Delphi versions, too. It's very fast and needs practically no memory. - IXMLDocument (OXmlPDOM.pas): Record-based DOM according to the W3C DOM Level 1 specification.
(Not strict - some small changes have been made to maximize performance).
The fastest and most memory-friendly DOM for Pascal. - IXMLDocument (OXmlCDOM.pas): TObject-based DOM according to the W3C DOM Level 1 specification.
(Not strict - some small changes have been made to maximize performance).
For those who don't like the "old-school" approach of OXmlPDOM.pas. There is some performance and memory consumption penalty, though. - TXMLSeqParser (OXmlSeq.pas): Sequential DOM parser based on OXmlPDOM.pas.
Read huge XML files into the DOM sequentionally. This method combines DOM capabilities without the need to load the whole document at once.
OXmlSeq is even a little bit faster than OXmlPDOM. - sOXmlDOMVendor (OXmlDOMVendor.pas): fastest DOM vendor for Delphi's own TXMLDocument.
Use TXMLDocument(MyXmlDoc).DOMVendor := GetDOMVendor(sOXmlDOMVendor) if you want to use Delphi's default TXMLDocument with the fastest and cross-platform vendor.
What are the differences between OXmlPDOM and OmniXML / MS XML?
- In general OXmlPDOM is very close to both implementations. They share the same functions and properties.
- OmniXML and MS XML are interfaced-based. That means that nodes are created
one-by-one and when they are not referenced any more, they are automatically destroyed.
OXmlPDOM is record-based. Nodes are created by groups of 1024 items, which offers stunning performance. They are automatically destroyed only when the owner XML document is destroyed. Therefore such functions do not free memory used by a node:- TXMLNode.RemoveChild()
- TXMLNode.ReplaceChild()
-
The nodes are of PXMLNode type - pointer to TXMLNode structure. Strictly speaking,
PXMLNode nodes have to be dereferenced to TXMLNode when used but
Delphi does this dereferencing for you, so you can easily use: XML.DocumentElement.AddChild('child');
If you use FPC/Lazarus in Delphi mode ({$MODE DELPHI}), the nodes get dereferenced too. But if you use FPC/Lazarus in default mode, you have to dereference it manually with the "^" operator: XML.DocumentElement^.AddChild('child');
If you don't like this approach, use OXmlCDOM.pas instead of OXmlPDOM.pas. - OXmlPDOM does not store child nodes and attributes in AttributeNodes and ChildNodes lists.
That means that the lists are created only when they are needed by the user. AttributeNodes and ChildNodes are not typical TList descendants but they are doubly linked lists with fast index iteration and count function support.
Migration table from OmniXML to OXml
OXml offers the same functionality as OmniXML but some functions/properties may have different names. The following table lists them:IXMLNode |
|
OmniXML | OXml equivalent |
---|---|
IXMLNode, IXMLElement, ... (interface) | PXMLNode (pointer to TXMLNode structure) |
SelectSingleElementNil() | SelectNodeNull() |
SelectSingleElementCreate() | SelectNodeCreate() |
SelectSingleElement() | SelectNode() |
SelectSingleNode() | SelectNode() |
Attributes | AttributeNodes |
Attributes.GetNamedItem() | GetAttributeNode() |
with Node do | with Node^ do |
if Supports(Node, IXMLElement) then | if Node.NodeType = ntElement then |
IXMLDocument |
|
OmniXML | OXml equivalent |
Load() | LoadFromFile() |
LoadXML() | LoadFromXML() |
Save() | SaveToFile() |
TOutputFormat [ofNone, ofFlat, ofIndent] | TXmlIndentType [itNone, itFlat, itIndent] |
*Self* (the DOM document node) | *Self*.Node |
CreateProcessingInstruction('xml', ...) | CreateXMLDeclaration |
Important: CreateProcessingInstruction exists in OXml too but should not be used for the <?xml ... ?> PI. For that specific PI, CreateXMLDeclaration should be used. Only so the encoding will be correctly detected when saving the document. | |
SaveToStream(Stream, ofIndent); | WriterSettings.IndentType := itIndent; SaveToStream(Stream); |
IXMLNodeList |
|
Length | Count |
Item[] | Nodes[] or [] (default) |
Performance optimizationsThe most important approach that is different to OmniXML and other parsers is that OXml doesn't use child and attribute lists natively. They have to be created if you want to use them, which is slow.Therefore avoid using ChildNodes and AttributeNodes wherever possible. Replace them with GetNextChild (GetNextAttribute) or with FirstChild+NextSibling (FirstAttribute+NextSibling) approach as shown below. The following table lists concepts that you used in OmniXML and that you can use in OXml as well but if you want maximum performance, you should consider replacing them. |
|
OmniXML | OXml equivalent |
if Node.ChildNodes.Count > 0 then | if Node.HasChildNodes then |
for I := 0 to Node.ChildNodes.Count-1 do begin ChildNode := Node.ChildNodes.Item[I]; [...] end; |
ChildNode := nil; while Node.GetNextChild(ChildNode) do begin [...] end;-- or -- ChildNode := Node.FirstChild; while Assigned(ChildNode) do begin [...] ChildNode := ChildNode.NextSibling; end; |
ChildNodes[0] (if used separately) | FirstChild |
ChildNodes[1] (if used separately) | ChildFromBegin[1] |
ChildNodes[ChildNodes.Count-1] (if used separately) | LastChild |
ChildNodes[ChildNodes.Count-2] (if used separately) | ChildFromEnd[1] |
Node.Attributes['attr'] := 'value' | Node.AddAttribute('attr', 'value') |
Example code
OXml should be very close to Delphi's IXMLDocument. Furthermore you can take advantage of new added functionality that makes creating and reading XML documents easier.Please take a short look into the source code for a full list of properties and methods. Everything should be commented in the source code.
Please see the DEMO application for your compiler (unicode Delphi, non-unicode Delphi, Lazarus) for more code!
Here is a short example code:
OXml DOM (OXmlPDOM.pas)
uses OXmlPDOM; procedure TestOXmlPDOM; var XML: IXMLDocument; Root, Node, Attribute: PXMLNode; begin //CREATE XML DOC XML := CreateXMLDoc('root', True);//create XML doc with root node named "root" Root := XML.DocumentElement; Node := Root.AddChild('child');//add child to root node Node.SetAttribute('attribute1', 'value1');//set attribute value Node := Root.AddChild('child'); Node.SetAttribute('attribute2', 'value2'); XML.SaveToFile('S:\test.xml');//save XML document //READ XML DOC XML := CreateXMLDoc;//create empty XML doc XML.LoadFromFile('S:\test.xml');//load XML document Root := XML.DocumentElement;//save the root into local variable //iterate through all child nodes -> you MUST set the node to nil Node := nil; while Root.GetNextChild(Node) do begin //iterate through all attributes -> you MUST set the node to nil Attribute := nil; while Node.GetNextAttribute(Attribute) do ShowMessage(Node.NodeName+'['+ Attribute.NodeName+'] = '+ Attribute.NodeValue); end; end;
OXml SAX (OXmlSAX.pas)
uses OXmlSAX; function SAXEscapeString(const aString: String): String; begin Result := aString; Result := StringReplace(Result, sLineBreak, '\n', [rfReplaceAll]); Result := StringReplace(Result, '"', '\"', [rfReplaceAll]); end; procedure TestOXmlSAX(const aOutputMemo: TMemo); var xSAX: TSAXParser; const cXML: String = '<?xml version="1.0"?>'+sLineBreak+ '<seminararbeit>'+sLineBreak+ ' <titel>DOM, SAX und SOAP</titel>'+sLineBreak+ ' <inhalt>'+sLineBreak+ ' <kapitel value="1">Einleitung</kapitel>'+sLineBreak+ ' <kapitel value="2">Hauptteil</kapitel>'+sLineBreak+ ' <kapitel value="3">Fazit</kapitel>'+sLineBreak+ ' </inhalt>'+sLineBreak+ ' <!-- comment -->'+sLineBreak+ ' <![CDATA[ cdata ]]>'+sLineBreak+ ' <?php echo "custom processing instruction" ?>'+sLineBreak+ '</seminararbeit>'+sLineBreak; begin aOutputMemo.Lines.Clear; xSAX := TSAXParser.Create; try xSAX.OnCharacters := ( procedure(aSaxParser: TSAXParser; const aText: OWideString) begin aOutputMemo.Lines.Add('characters("'+SAXEscapeString(aText)+'")'); end); xSAX.OnStartElement := ( procedure(aSaxParser: TSAXParser; const aName: String; const aAttributes: TSAXAttributes) var xValueAttr, xAttrStr: String; begin if aAttributes.Find('value', xValueAttr) then xAttrStr := 'value="'+SAXEscapeString(xValueAttr)+'"' else xAttrStr := '[[attribute "value" not found]]'; aOutputMemo.Lines.Add( 'startElement("'+SAXEscapeString(aName)+'", '+xAttrStr+')'); end); xSAX.OnEndElement := ( procedure(aSaxParser: TSAXParser; const aName: String) begin aOutputMemo.Lines.Add('endElement("'+SAXEscapeString(aName)+'")'); end); xSAX.ParseXML(cXML); finally xSAX.Free; end; end;
OXml DOM vendor (OXmlDOMVendor.pas)
uses XmlIntf, XmlDoc, OXmlDOMVendor; procedure TestOXmlVendor(const aOutputMemo: TMemo); var xXml: XmlDoc.TXMLDocument; xXmlI: XmlIntf.IXMLDocument; xRoot: XmlIntf.IXMLNode; begin xXml := XmlDoc.TXMLDocument.Create(nil); xXml.DOMVendor := xmldom.GetDOMVendor(sOXmlDOMVendor); xXmlI := xXml; //now use xXmlI just like every other TXMLDocument xXmlI.Active := True; xRoot := xXmlI.Node.AddChild('root'); xRoot.ChildNodes.Add(xXmlI.CreateNode('text', ntText)); xRoot.ChildNodes.Add(xXmlI.CreateNode('node', ntElement)); aOutputMemo.Lines.Text := xXmlI.Node.XML; end;
License
OXml is available under commercial license.OXml Commercial License ----------------------- Author, initial developer of the OXml library: Copyright (C) 2011-2017 Ondrej Pokorny http://www.kluug.net All rights reserved. This license applies to orders after April 10th, 2017. *** BEGIN LICENSE BLOCK ***** OXml LICENSE ------------ 1) Usage You may use OXml for any kind of end-user applications developed only by you (single-development license) or the company (company license) that purchased an OXml license. 2) Limitations a. Only developers who work for the license holder company may use OXml. That includes freelancers but only in projects assigned to them by the license holder company. b. The number of active developers who use OXml must not exceed the total number of licensed developers that the license(s) of the holder company provide(s) for. c. You must not use OXml for writing libraries and applications that are in direct or indirect competition with OXml or tools whose main purpose is providing OXml functionality. OXml functionality has to be an extension to an existing application (e.g. import/export XML data in an accounting software). If you need a special license, please contact the author. 3) Transfer of FULL version licenses a. Licenses may be transferred to new developers who work for the license holder company if all other requirements are met (especially point 3b). b. The license may be transferred only as a whole to a different company. Example: you buy a 3-developer license. You may transfer it completely to a different company. You must not split the license and transfer 1-developer license to a different company and keep 2-developer license. 4) License validity a. The license is perpetual. b. You get 2 years of free updates and new releases, starting from the day of purchase. After this period you can order extra 2 years of updates (starting from the day of update expiration) for 60% of the license price at the moment of update expiration. 5) Redistribution of the source code and the DCU's a. OXml source code and DCU's must not be redistributed on any kind of media or offered for download on any internet server without the author's explicit permission. 6) Limited Warranty a. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT SHALL KLUUG.NET OR ANY OTHER PARTY WHO MAY HAVE DISTRIBUTED THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ***** END LICENSE BLOCK *****
Performance
The following performance test can be found in the DEMO application and you can run it for yourself.All figures in the following tables are the best achieved values from more tests.
As you can see, OXml DOM's (OXmlPDOM.pas) overall reading and writing performance
is the best across all compilers. It is even a little bit better than the C-based libxml2 ported to Delphi (DIXml).
Furthermore, it's also the least memory hungry DOM.
The slightly worse non-unicode Delphi (D7) performance is a result of Delphi's poor WideString performance.
Read Test
The read test returns the time the parser needs to read a custom XML DOM from a file (column "load")
and to write node values to a constant dummy function (column "navigate"). Win32 Delphi XE2:PC: Intel Core 2 Duo laptop from 2007 [1] |
|||||||||
Library | unit | load | navigate | load+navigate | memory | ||||
---|---|---|---|---|---|---|---|---|---|
[s] | % | [s] | % | [s] | % | [MB] | % | ||
OXml DOM | OXmlPDOM.pas | 0,61 | 100 | 0,11 | 100 | 0,72 | 100 | 34 | 100 |
OXml sequential DOM | OXmlSeq.pas | 0,55 | 90 | 0,08 | 73 | 0,63 | 88 | 0,2 | 1 |
OXml SAX parser | OXmlSAX.pas | 0,36 | 59 | 0,01 | 9 | 0,37 | 51 | 0,1 | 0 |
OXml direct reader | OXmlReadWrite.pas | 0,36 | 59 | 0,01 | 9 | 0,37 | 51 | 0,1 | 0 |
Delphi XML + OXml vendor | XMLIntf.pas, OXmlDOMVendor.pas | 0,59 | 97 | 3,51 | 3191 | 4,10 | 569 | 325 | 956 |
Delphi XML + MSXML vendor | XMLIntf.pas, msxmldom.pas | 1,23 | 202 | 5,89 | 5355 | 7,12 | 989 | 443 | 1303 |
Delphi XML + ADOM vendor | XMLIntf.pas, adomxmldom.pas | 11,98 | 1964 | 3,56 | 3236 | 15,54 | 2158 | 503 | 1479 |
MSXML | msxml.pas | 1,23 | 202 | 3,32 | 3018 | 4,55 | 632 | 36 | 106 |
OmniXML (SVN) | OmniXML.pas | 2,22 | 364 | 0,83 | 755 | 3,05 | 424 | 92 | 271 |
NativeXml | NativeXml.pas | 4,43 | 726 | 0,87 | 791 | 5,30 | 736 | 57 | 168 |
SimpleXML | SimpleXML.pas | 0,87 | 143 | 0,52 | 473 | 1,39 | 193 | 76 | 224 |
DIXml (libxml2) | DIXml.dcu | 0,34 | 56 | 0,42 | 382 | 0,76 | 106 | 65 | 191 |
Alcinoe DOM | AlXmlDoc.pas | 2,65 | 434 | 0,84 | 764 | 3,49 | 485 | 96 | 282 |
Alcinoe SAX | AlXmlDoc.pas | 1,65 | 270 | 0,52 | 473 | 2,17 | 301 | 0 | 0 |
VerySimpleXML | Xml.VerySimple.pas | failed | |||||||
Win32 Delphi 7:PC: Intel Core 2 Duo laptop from 2007 [1] |
|||||||||
Library | unit | load | navigate | load+navigate | memory | ||||
[s] | % | [s] | % | [s] | % | [MB] | % | ||
OXml DOM | OXmlPDOM.pas | 0,98 | 100 | 0,27 | 100 | 1,25 | 100 | 34 | 100 |
OXml sequential DOM | OXmlSeq.pas | 0,94 | 96 | 0,20 | 74 | 1,14 | 91 | 0,2 | 1 |
OXml SAX parser | OXmlSAX.pas | 0,62 | 63 | 0,01 | 4 | 0,63 | 50 | 0,1 | 0 |
OXml direct reader | OXmlReadWrite.pas | 0,62 | 63 | 0,01 | 4 | 0,63 | 50 | 0,1 | 0 |
Delphi XML + OXml vendor | XMLIntf.pas, OXmlDOMVendor.pas | 1,00 | 102 | 6,72 | 2489 | 7,72 | 618 | 280 | 824 |
Delphi XML + MSXML vendor | XMLIntf.pas, msxmldom.pas | 1,22 | 124 | 6,76 | 2504 | 7,98 | 638 | 409 | 1203 |
MSXML | msxml.pas | 1,22 | 124 | 3,45 | 1278 | 4,67 | 374 | 36 | 106 |
OmniXML (SVN) | OmniXML.pas | 4,67 | 477 | 1,78 | 659 | 6,45 | 516 | 78 | 229 |
NativeXml | NativeXml.pas | 5,02 | 512 | 1,56 | 578 | 6,58 | 526 | 44 | 129 |
SimpleXML | SimpleXML.pas | 1,11 | 113 | 1,28 | 474 | 2,39 | 191 | 54 | 159 |
DIXml (libxml2) | DIXml.dcu | 0,39 | 40 | 1,23 | 456 | 1,62 | 130 | 63 | 185 |
Win32 Lazarus 1.0.8:PC: Intel Core 2 Duo laptop from 2007 [1] |
|||||||||
Library | unit | load | navigate | load+navigate | memory | ||||
[s] | % | [s] | % | [s] | % | [MB] | % | ||
OXml DOM | OXmlPDOM.pas | 0,89 | 100 | 0,09 | 100 | 0,98 | 100 | 36 | 100 |
OXml sequential DOM | OXmlSeq.pas | 0,83 | 93 | 0,06 | 67 | 0,89 | 91 | 0,2 | 1 |
OXml SAX parser | OXmlSAX.pas | 0,58 | 65 | 0,01 | 11 | 0,59 | 60 | 0,1 | 0 |
OXml direct reader | OXmlReadWrite.pas | 0,56 | 63 | 0,01 | 11 | 0,57 | 58 | 0,1 | 0 |
OmniXML (SVN) | OmniXML.pas | 3,74 | 420 | 1,17 | 1300 | 4,91 | 501 | 132 | 367 |
NativeXml | NativeXml.pas | 4,23 | 475 | 1,44 | 1600 | 5,67 | 579 | 72 | 200 |
Lazarus DOM | DOM.pas | 0,89 | 100 | 0,84 | 933 | 1,73 | 177 | 97 | 269 |
Write Test
The write test returns the time the parser needs to create a DOM (column "create") and write this DOM to a file (column "save"). Win32 Delphi XE2:PC: Intel Core 2 Duo laptop from 2007 [1] |
|||||||||
Library | unit | create | save | create+save | memory | ||||
[s] | % | [s] | % | [s] | % | [MB] | % | ||
OXml DOM | OXmlPDOM.pas | 0,34 | 100 | 0,31 | 100 | 0,65 | 100 | 48 | 100 |
OXml direct writer | OXmlReadWrite.pas | 0 | 0 | 0,30 | 97 | 0,30 | 46 | 0,1 | 0 |
Delphi XML + OXml vendor | XMLIntf.pas, OXmlDOMVendor.pas | 4,35 | 1279 | 0,31 | 100 | 4,66 | 717 | 296 | 617 |
Delphi XML + MSXML vendor | XMLIntf.pas, msxmldom.pas | failed | |||||||
Delphi XML + ADOM vendor | XMLIntf.pas, adomxmldom.pas | 6,82 | 2006 | 10,55 | 3403 | 17,37 | 2672 | 543 | 1131 |
MSXML | msxml.pas | 4,31 | 1268 | 0,39 | 126 | 4,70 | 723 | 76 | 158 |
OmniXML (SVN) | OmniXML.pas | 1,36 | 400 | 0,94 | 303 | 2,30 | 354 | 126 | 262 |
NativeXml | NativeXml.pas | 4,17 | 1226 | 1,54 | 497 | 5,71 | 878 | 78 | 162 |
SimpleXML | SimpleXML.pas | 0,64 | 188 | 1,09 | 352 | 1,73 | 266 | 119 | 248 |
DIXml (libxml2) | DIXml.dcu | 0,36 | 106 | 0,53 | 171 | 0,89 | 137 | 92 | 192 |
Alcinoe DOM | AlXmlDoc.pas | 0,94 | 276 | 1,20 | 387 | 2,14 | 329 | 110 | 229 |
VerySimpleXML | Xml.VerySimple.pas | 0,61 | 179 | 1,81 | 584 | 2,42 | 372 | 127 | 265 |
Win32 Delphi 7:PC: Intel Core 2 Duo laptop from 2007 [1] |
|||||||||
Library | unit | create | save | create+save | memory | ||||
[s] | % | [s] | % | [s] | % | [MB] | % | ||
OXml DOM | OXmlPDOM.pas | 0,62 | 100 | 0,73 | 100 | 1,35 | 100 | 48 | 100 |
OXml direct writer | OXmlReadWrite.pas | 0 | 0 | 0,61 | 84 | 0,61 | 45 | 0,1 | 0 |
Delphi XML + OXml vendor | XMLIntf.pas, OXmlDOMVendor.pas | 7,10 | 1145 | 0,75 | 103 | 7,85 | 581 | 253 | 527 |
Delphi XML + MSXML vendor | XMLIntf.pas, msxmldom.pas | failed | |||||||
MSXML | msxml.pas | 4,59 | 740 | 0,34 | 47 | 4,93 | 365 | 80 | 167 |
OmniXML (SVN) | OmniXML.pas | 2,98 | 481 | 3,01 | 412 | 5,99 | 444 | 104 | 217 |
NativeXml | NativeXml.pas | 4,74 | 765 | 2,75 | 377 | 7,49 | 555 | 60 | 125 |
SimpleXML | SimpleXML.pas | 2,31 | 373 | 2,61 | 358 | 4,92 | 364 | 79 | 165 |
DIXml (libxml2) | DIXml.dcu | 1,14 | 184 | 1,28 | 175 | 2,42 | 179 | 87 | 181 |
Win32 Lazarus 1.0.8:PC: Intel Core 2 Duo laptop from 2007 [1] |
|||||||||
Library | unit | create | save | create+save | memory | ||||
[s] | % | [s] | % | [s] | % | [MB] | % | ||
OXml DOM | OXmlPDOM.pas | 0,50 | 100 | 0,39 | 100 | 0,89 | 100 | 44 | 100 |
OXml direct writer | OXmlReadWrite.pas | 0 | 0 | 0,41 | 105 | 0,41 | 46 | 0,1 | 0 |
OmniXML (SVN) | OmniXML.pas | 1,92 | 384 | 2,01 | 515 | 3,93 | 442 | 143 | 325 |
NativeXml | NativeXml.pas | 4,23 | 846 | 1,59 | 408 | 5,82 | 654 | 100 | 227 |
Lazarus DOM | DOM.pas | 0,84 | 168 | 1,16 | 297 | 2,00 | 225 | 87 | 198 |
Download
Please be sure you check the license information before downloading any of the files below.OXml TRIAL package
Installation
OXml is a runtime library. Just add the source code directory to your Delphi library path.If you want to (or need) you can compile the supplied package for your Delphi version.
Order
You may order a roality-free commercial license for a specified number of developers using OXml in your company. A commercial license allows you to use OXml in any kind of end-user application.
The license applies to OXml version available at the moment of purchase and all OXml updates released within 2 years after the purchase.
Pricing & Order
Online orders are managed by PayPal. I also accept bank transfers to my bank account. In this case, please send me an email with your billing address and I send you my account number.
You receive an invoice per email after your payment.
All prices are without VAT.
I offer you a 30-days money-back guarantee if you can't use OXml for what is advertised on this page (because of bugs, compatibility problems etc.).
Commercial licenses
OXml + DataBinding + OJson bundle: this includes the whole OXml package with all XML and JSON units and the DataBinding project - the ability to generate and include PAS-XSD bindings in your software.
OXml + DataBinding + OJson for 1 developer + 2 years of updates |
EUR 500,- (~ USD 500,-) | |
---|---|---|
OXml + DataBinding + OJson for max. 3 developers within one company + 2 years of updates |
EUR 1000,- (~ USD 1000,-) | |
OXml + DataBinding + OJson for max. 5 developers within one company + 2 years of updates |
EUR 1500,- (~ USD 1500,-) | |
OXml + DataBinding + OJson for unlimited developers within one company + 2 years of updates |
EUR 2000,- (~ USD 2000,-) |
OXml XML only: this includes only the XML part of OXml package with DOM, SAX, XML serialization etc. JSON and DataBinding capabilities are not included.
OXml for 1 developer + 2 years of updates |
EUR 150,- (~ USD 150,-) | |
---|---|---|
OXml for max. 3 developers within one company + 2 years of updates |
EUR 300,- (~ USD 300,-) | |
OXml for max. 5 developers within one company + 2 years of updates |
EUR 450,- (~ USD 450,-) | |
OXml for unlimited developers within one company + 2 years of updates |
EUR 600,- (~ USD 600,-) |
OXml + OJson: this includes the XML and JSON units of OXml package with DOM, SAX, XML&JSON serialization etc. DataBinding capabilities are not included.
OXml + OJson for 1 developer + 2 years of updates |
EUR 250,- (~ USD 250,-) | |
---|---|---|
OXml + OJson for max. 3 developers within one company + 2 years of updates |
EUR 500,- (~ USD 500,-) | |
OXml + OJson for max. 5 developers within one company + 2 years of updates |
EUR 750,- (~ USD 750,-) | |
OXml + OJson for unlimited developers within one company + 2 years of updates |
EUR 1000,- (~ USD 1000,-) |
Change log
OXml Change Log --------------- Version 2.15 2024-01-03 - Delphi 12 support - OXmlSerialize: array of Integer/Int64 support - OXml*Seq: namespace support - XSLT: support attribute value templates - XSLT: ExecuteXPath with namespaces from the template - XLST: Handle the output indent attribute - XSLT: fix number-format() - XSLT: support xsl:version attribute in literal result elements - XSLT: fix loading external documents - XSLT: support xsl:template mode - XSLT: support xsl:template priority - XSLT: default encoding for transformation output is UTF-8 - OXmlCreateDataBinding: Encoding + WriteBom - XPath: support escaped quotes in string literals as of XPath 2.0 - XPath: empty selector prefix is always NULL namespace - XPath: Fix OR operator - XPath: fix operator evaluation - XPath not(): fix handling (should be exactly the same as with boolean() but negated) - XPath: fix variable data node determination - XPath: fix comparison of node lists - compare all values - XPath: add exists() function - XPath: fix creating bracket expressions - XPath: fix /-operator (TRPNTokenExecuteXPathOperator) precedence - XPath: move function current() to XSLT - OExpressionEvaluation: IRPNToken: rename Calculate to ApplyParameters and validate the expression stack in LoadFromPChar - OExpressionEvaluation: do not evaluate unneeded operands for logical operators - OExpressionEvaluation: do not evaluate unneeded function parameters and operands - OExpressionEvaluation: more exact comparison operator handling - OExpressionEvaluation: add TRPNTokenIgnore - OExpressionEvaluation: improve exception handling - OExpressionEvaluation: TRPNExpression: add mathematical errors to a list to inform the user about them - JSON (de)serializer: support UseUTCTime - JSON (de)serializer: support array (first version) - JSON: add ttNumber constant - JSON: allow (ignore) line breaks in string constants - TCustomJSONReader.ReadObject with StrictObjects - do not ignore unknown properties - ISOStrToDateTimeDef: add aReturnUTC attribute - ISOTryStrToDateTime: no TZ defined means local time and has to be converted to UTC according to ISO 8601 - ISOTryStrToTime: fix 00Z time stamp - TOHashedObjDictionary: new dictionary type - TOHashedDictionary: fix replacing items with Add() Version 2.14 2023-01-01 - TXMLWhiteSpaceHandling breaking change: split into TXMLWhiteSpaceHandling and TXMLWhiteSpaceRemoveType. Old value = TXMLWhiteSpaceHandling + TXMLWhiteSpaceRemoveType combination: - wsTrim = wshRemove + wsrTrim - wsPreserveInTextOnly = wshRemove + wsrRemoveBetweenTags - wsPreserveAll = wshPreserve - wsAutoTag = wshAutoTag + wsrTrim - DoStringToStreamConversion - JSON fix exception - JSON ReaderSettings.NullAsDefault - JSONReader.ReadCollectionItems: fix reading empty collection - OXmlSerialize: don't serialize nil objects - XSLT: format-number() and xsl:decimal-format support - DataBinding: Fix for empty import tag - OExpressionEvaluation: check for unfinished expressions - OExpressionEvaluation: support 1-operators with left operands (e.g. %) - ExpressionEvaluation: better error messages - ExpressionEvaluation: SourcePos - OXml: FastNameSpaces default value = False - OXml: refactoring for more extension possibilities - OJsonPTree: FindCreatePairValue - OXmlCDOM: expose bugs from fix PreloadNamespaces for unittests - OXmlCDOM: fix PreloadNamespaces - CreateDataBinding: add xs:gYear, xs:gMonth, xs:gDay types - OXmlSAX: fix OnEndThisElement for not-opened elements () - CreateDataBinding: fix search for used DB files - OXml tests: add multidatabinding tests - circular dependencies are now resolved - CreateDataBinding: remove -SingleUnit and implement automatic circular dependency detection - CreateDataBinding: fix file search from namespace - CreateDataBinding: fix temp file extension - CreateDataBinding: -SingleUnit fix compilation - CreateDataBinding: fix tests - CreateDataBinding: fix uses for namespaces - CreateDataBinding: -SingleUnit - CreateDataBinding: -tempdir - CreateDataBinding: fix parent class for simple types - JSONPath document operators - CreateDataBinding: fix XML root names - CreateDataBinding: allow to generate HTTP files - OXml: ReaderSettings.IgnoreErrors - DataBinding: fix TDataBindingNode.ISODateTimeToStr - ISOTryStrToTime fixes - OXmlReadWrite: allow <>> in the reader in non-strict mode - rename TRPNTokenNullResult -> TRPNTokenNull - xsltransformation: whitespace handling - XSLT: fix whitespace handling - XSLT: fix template nodes for ExecuteXPath - rename TRPNTokenNullResult -> TRPNTokenNull - XPath: fix null implicit conversions - XSLT: fix IsHTMLVoidElement - JSONPath: allow functions with multiple parameters Version 2.13 2022-03-25 Short list: - A complete rewrite of the XSL transformation engine: * You will have to remove OXmlCTransform, OXmlPTransform form the uses clause and use OXmlTransformEngine instead. * You will probably have to change the code slightly to match new method headers. - JSONPath: remove external filter - it is not standardized and should be replaced with JSONPath expressions - A lot of XPath fixes - if you use low-level access, you will have to change the code slightly to match new method headers. Long list: - CreateDataBinding: EXE info in the header - CreateDataBinding: fix searching for files - TJSONDocument: GetDocumentObject, GetDocumentArray - OXmlReadUntilIs with TByteSet - TJSONPath: LoadFromPChar with aStopAtChar - JSONPath: support functions, remove external filter - OXmlTransformEngine: fix auto-generating XHTML - OXmlTransformEngine: fix copy-of XSLTVariable processing - OXmlTransformEngine: better test for sort - OXmlTransformEngine: fixes for XPath select of for-each and its sort - OXmlXPath: MatchNode - OXmlXPath: [] fix for custom results - OXmlXPath: position() fixes - OXmlXPath: fix equal operator for nodes - OXmlXPath: remove the text() function - it does not exist - OXmlTransformEngine: process variable nodes - XPath: fix null variable result - OXmlCDOM: TXMLDocument.PreloadNamespaces - XSLTransformation demo: stream refactoring - XSLTransformation demo: allow CDOM, HTTP(S) downloads for source files - XPath: fix white space after double slash and dot - XPath: fix white space after slash - XSLTransformation project - OXmlTransformEngine: HTML and encoding handling - OXmlTransformEngine: default HTML output according to root element - OXmlTransformEngine: fix standalone=omit output - OXmlTransformEngine: fix default template handling - OXmlTransformEngine: support external document loading in document() XPath function - OXmlTransformEngine: support $-variables returning node lists, and selecting further from them - XPath: support $-variables returning node lists, and selecting further from them - OXmlTransformEngine: handle default templates - OXmlTransformEngine: refactoring ProcessTemplateNode/ProcessChildren - OXmlTransformEngine: fix namespace manager in ProcessTemplates - OXmlTransformEngine: fix evaluating params from other files - OXmlTransformEngine: switch logic in ProcessTemplates - OXmlTransformEngine: precreate templates as TXSLTTemplate - OXmlTransformEngine: fix starting point for transformation - OXmlXPath: fix memory leak - OXmlTransformEngine: support xsl:variable - OXmlTransformEngine: fix xsl:template match - XPath: fix indexed node (/node[i]) resolution in XPath branches - OXmlTransformEngine: support raw text output (disable-output-escaping or text output format) - OXmlTransformEngine: xsl:number support format - OXmlTransformEngine: fix unit test - OXmlTransformEngine: fix whitespace handling - OXmlTransformEngine: write directly to stream - OXmlTransformEngine: do not clone empty text - OXmlTransformEngine: fix AV - OXmlTransformEngine: whitespace handling - OXml*DOM: namespaces only for attributes and elements - OXmlTransformEngine: ignore comments in the template - OXmlTransformEngine: export CDATA as text in HTML mode - OXmlTransformEngine: xsl:output fix standalone default value - OXmlTransformEngine: xsl:output - OXml*DOM: ICustomXMLDocument - OXmlTransformEngine: custom XSLT object - OXmlTransformEngine: fix templates with both match and name defined - OXml transformation engine: fix xsl:param visibility - Lazarus package: remove OXmlCTransform, OXmlPTransform (use OXmlTransformEngine in the uses clause instead) - OXml transformation engine: xsl:copy-of, xsl:number - OXml*DOM: IXPath object with a event callback for variables - OXml*DOM: simplification - XPath: preparation for variables - OXml transformation engine: xsl:import, xsl:apply-templates - XPath: fix "node::child()" XPath evaluation + unit test - OXml transformation engine: fix choose when result calculation - OXml transformation engine: call-template: no error when template not found - OXml transformation engine: support namespaces - XPath: support expressions at the end of the XPath - //element/(@count * @price) - OXml demo: XSL transformation - DOM: append in case aBeforeNode=nil in Insert - Fix docs about ErrorHandling - OXmlReadWrite: introduce OXmlDefReaderSettings, OXmlDefWriterSettings as global defaults. OXmlDefErrorHandling is replaced with OXmlDefReaderSettings.ErrorHandling - TOHashedStringDictionary.CaseSensitive also for Values - OExplode: fix text after the last delimiter - OXmlCreateDataBinding: add the possibility to change default options for the Get/Load/New* functions - parameters for the exe tool - OXmlCreateDataBinding: add the possibility to change default options for the Get/Load/New* functions - OXmlPDataBinding: add dboAutoCreateNodes and dboUTCDateTime options - OXmlDOMVendor: fix ParseError usage - it can be nil - OXmlDOMVendor: transformNode Version 2.12 2021-09-30 - Delphi 11 packages - DataBinding: TDataBindingNode.RegisterNameSpace only if the namespace isn't already registered - OXml*DOM: use TXMLChildType in FindNameSpacePrefixByURI - OXmlCreateDataBinding: use SetAttribute() instead of SetAttributeNS() and remove unwanted optimizations for attributes with empty namespaces - OXml*DOM: fix FindNameSpacePrefixes with redeclared namespace prefixes - OXml*DOM: add namespace-aware AddChild() and SetAttribute() overloads - Unit tests: EmptyNamespace - OXmlCDOM: empty namespace is also a valid namespace - OXmlReadWrite: breaking change: change the default error handling to ehRaise and introduce OXmlDefErrorHandling to allow to customize the default value - OXml*Seq: do not ResetDocumentElement - OXmlReadWrite: fix reading DTD comments and quoted strings - OXmlPDOM: empty namespace is also a valid namespace - OXml: fix text outside the document element - OXml reader: check for empty document and text outside the document element - JSON demo: ConvertXMLToJSON - JSON reader: ReadObjectOrArrayToObjectList: check range - Fix ISOFormatSettings - DataBinding: support restriction elements with modified types from base type - TOTextWriter.ReopenFile - OXml unittest: OExplode - OExplode: support brackets as quote chars - TOTextWriter.FileName - OJson: DateTimeTZ - DEMO: JSON writer - Fix packages for Delphi 2007 Version 2.11 2021-06-09 - DataBinding: TargetFilePrefix - DataBinding: resolve circular dependencies within objects for correct namespaces - DataBinding: allow empty namespace prefixes - DataBinding: search for uses within namespaces - DataBinding: register implicit nodes with their namespaces - DataBinding: Parse XSD: first search for imports, then types and at last for elements/attributes so that all types are available - TXMLNode.TransformNode: handle aStyleSheet=nil - DataBinding: improve header - DataBinding: optimize RegisterNameSpaces - write only really used namespaces - DataBinding: fix UsedDataBinding units creating - DataBinding: fix RegisterNameSpaces overrides - DataBinding: prevent duplicates in uses databinding units in whole tree - fix begin/end block - DataBinding: fix namespaces in inherited root elements - DataBinding: prevent duplicates in uses databinding units in whole tree - fix unassigned Result - DataBinding: prevent duplicates in uses databinding units in whole tree - DataBinding: use constants where possible - DataBinding: fix list for xml:anyType - DataBinding: fix output file with no types - DataBinding: cXMLSchema -> XML_XMLSCHEMA_URI - DOM: xml namespace is always defined - DataBinding: improve exceptions - DataBinding: AddTypeToLists when changing list type - DataBinding: fix list types - sometimes there were xltSingle but had to be xltFull - DataBinding: write OXml version - DataBinding: fix TObjectInfoItem.GetWriteXMLDoc - DataBinding: fix root elements with parents - DataBinding: handle anyType restriction/extension base - DataBinding: fix generating AnyType lists - DOM: fix TXMLNode.GetNodePath for non-element nodes - DataBinding: fix creating implicit types - check the node type contents and not the name - OGetLocalTimeOffset: load GetTimeZoneInformationForYear dynamically - TEncoding.CodePage for Delphi 2009-2010 Version 2.10 2021-02-02 - DOM: AV when closing too many elements in StrictXML=False - DOM: better fix for empty NameSpaceURIs - DOM: fix FindNameSpacePrefixByURI for an empty NameSpaceURI - DOM: fix FindNameSpacePrefixByURI for an empty NameSpaceURI - CreateDataBinding: add duration type - CreateDataBinding: fix write imported extended interfaces - CreateDataBinding: support xs:anyType and xs:anySimpleType - DataBinding: anyType is a complex type - DataBinding: do not repeat restrictions - DataBinding: fix FindBaseOfSimpleTypeNode for external databinding units - DataBinding: fix duplicate list types - DataBinding: fix filename handling - DataBinding: fix simple type aIsChildOfMultiList - DataBinding: fix substitution namespace - DataBinding: support for empty (anyType - all attributes and elements allowed) element - DataBinding: use explicit unit name for class&interface definitions from external databinding files in order to solve name clashes - IDataBindingNodeList: Remove, RemoveAll, DeleteAll, GetEnumerator - IDataBindingNodeList: ToArray, AppendFromArray - ISOTryStrToTime: support 2-digit milliseconds - OEncoding: thread safety for old Delphi versions - OJsonPTree: add TJSONNode.GetNodePath - OJsonRttiSerialize: allow null in object&interface values - OJsonRttiSerialize: auto-create nil object/interface properties when deserializing - OJsonRttiSerialize: correctly deserialize empty objects - OXml: remove LazUtils dependency - OXmlCreateDataBinding: include files that cannot be imported from external PAS file - OXmlDOMVendor: fix appending cloned node from a different document - OXmlRttiSerialize: allow null in object&interface values - OXmlRttiSerialize: auto-create nil object/interface properties when deserializing - TJSONNode.AddPair Variant value - TRPNExpression.Evaluate - TXMLNode.DeleteEmptyNodes - unit test - TXMLWriterElement additions - XPath: fix namespace-uri function name - XSL transformation: don't eat exceptions - add TXMLNode.DeleteEmptyNodes Version 2.9 2020-07-23 - breaking change/fix: DOM: fix NameSpaceURI for attributes (2.8 and older reported wrong namespaces for unprefixed attributes) - new feature: XSL transformation engine (XSLT) - new feature: JSONToXML converter (OJsonPXml.pas) - DataBinding: support union simpleType - JSONPath: support * in arrays - DOMVendor: don't write BOM - OXmlPDOM: correctly clear fTempAttributeIndex - ISOTryStrToDate: allow time zone acording to XSD specification - ISOTryStrToDate: new overload to return time zone information - OJsonPTree: public CloneNode/Append/InsertBefore/Remove - XPath: comment(), processing-instruction() - XPath: fix performance bottleneck: use global function dictionary Version 2.8 2020-05-12 - DOM: add Delete to TXMLResNodeList + fix Insert in CDOM - XPath: implement XPath axes - XPath functions: fix TRPNFunctionTranslate result - XPath functions: string-join, replace, normalize-space - XPath functions: fix substring-after and substring-before - XML reader: nonstrict mode: fix reading attribute values without quotes - OJsonRttiSerialize: fix deserialize of datetime variants - DataBinding: fix list item insert parameter type - DataBinding: fixes for unqualified include files Version 2.7 2019-12-18 - CreateDataBinding: create separated PAS units for every included XSD - XPath: fix text node value evaluation - JSONPath, XPath: fix equality evaluation Version 2.6 2019-11-26 - Delphi 10.3.3 support (with Android 64bit support) - XML: complete XPath rewrite with better performance and expression evaluation - XML: Read invalid entity names in non-strict mode - JSON: JSONPath support (with expression evaluation) - JSON: support EJSON DateTime and TStream - JSON: decouple Int64 and Extended because on some platforms Extended doesn't have enough range for Int64 - JSON serializers: allow to auto-detect simple type value structure (object/non-object) - JSON & XML serializers: fix Int64 properties - JSON & XML serializers: Base64 support - JSON & XML serializers: enhanced Spring4D 2.0 support - DataBinding: fix qualified attribute generation - DataBinding: fix unqualified element generation - DataBinding: fix list generation (list was not generated if minOccurs=maxOccurs) - DataBinding: write namespace constants in the interface section so that they are available in other units - DataBinding: correctly handle relative paths - ISODate* utils: make format strings locale independent - Delphi pre-D2009 support for unicode filenames Version 2.5 2019-07-27 - Delphi 10.3.2 support (with MacOS 64bit support) - fixed AV in Delphi Release mode - OXmlRttiSerialize: support Spring4D 2.0 - OTextReadWrite: fix incorrect UTF-8 character handling - DataBinding: allow custom conversion functions - DataBinding: fix element selector Version 2.4 2019-06-13 - DOM: support nodes with attributes in SelectNodeCreate - DOM: SelectNode&SelectNodes with multiple namespace support - DOM vendor: support DOMDocument.importNode - DataBinding: various improvements and enhancements - implement JSON RTTI serializer / deserializer Version 2.3 2018-12-31 - Delphi 10.3 support - Fix D7 compilation - ODictionary: add Text function - TXMLNode.SelectNodeCreate: support root paths (//test/hello) - CreateDataBinding: add Delphi mode - OXmlPDOM, OXmlCDOM: publish TXMLDocument.UseReadNameSpaceURI - Fix StrToInt??? for Cardinal/Int64/UInt64 - Fix TXMLNode.InsertProcessingInstruction, TXMLNode.InsertText - Extend ISOTryStrToTime, ISOTryStrToDate, ISOTryStrToDateTime - OXmlCDOM, OXmlPDOM: new WriterSettings.AddLineBreakOnFileEnd property - OXmlRTTISerialize: fix GetCollectionItemXMLName Version 2.2 2018-10-24 - Extensively improved OXmlPDataBinding.pas - improved RTTI serializer Version 2.1 2017-06-12 - Extensively improved OXmlPDataBinding.pas Version 2.0 2017-05-04 - New JSON features: * OJsonPTree.pas (similar to OXmlPDOM.pas) * OJsonEvent.pas with class handlers (similar to OXmlSAX.pas) - OXmlPDataBinding.pas + databinding application in databinding directory: data binding for OXmlPDOM.pas - Fix ISOStrTo* functions - raise an exception on error - RTTI serializer: add Options set, change WriteDefaultValues to Options.xsoWriteDefaultValues, add xsoWriteReadOnlyProperties - OXmlRTTISerialize: fix TDate/TTime/TDateTime serialization - OXmlUtils: add TryStrToDate for Delphi 5 - OXmlUtils: add ISO*Int64 functions. - OHashedStrings: add TOHashedIntegerList, TOHashedExtendedList - OHashedStrings: TOHashedStringObjDictionary: implement AddPObject - OXmlPDOM, OXmlCDOM: add attribute/child enumerators. - OXmlCSeq, OXmlPSeq, OXmlReadWrite: add property Eof. - OHashedStrings: fix performance bottleneck in clearing nodes (shows in sequential parser). Version 1.10 2016-04-06 [SVN commit: 126, https://sourceforge.net/p/oxml/code/126/] - Implement extensive namespace support for DOM reading. - Check length of string/buffer before calling SetLength (small performance gain). - Fix TOHashedStringObjDictionary.Delete, delete also fObjects item. - Add TCustomXMLWriterSettings.EscapeQuotes to force escaping single and double quotes. Patch from Luis Moreno - Add TXMLNode.SelectNodesNS - Fix memory leak in OXmlSAX when reading an empty document. - Updated demos, added Delphi 5 demo and added information about why OXmlDOMVendor isn't supported on Delphi 5. Version 1.9 2015-12-07 [SVN commit: 112, https://sourceforge.net/p/oxml/code/112/] ! Breaking change: TXMLNode.GetElementsByTagName (OXmlPDOM.pas and OXmlCDOM.pas) now uses recoursive search by default to comply with XML standards. ! Breaking change: Fixed bug in TXMLSerializer and TXMLDeserializer: UseRoot is True now by default ! - Added OTrim in OWideSupp.pas. - Fixed missing Math unit under non-Win FPC. - Fixed bug in OXmlDOMVendor.pas: TOXmlDOMElement.getElementsByTagName and TOXmlDOMDocument.getElementsByTagName - OXmlSAX.pas: added support for an external class handler that can be nestable. - JSON code reworked: deleted JSON.pas, added OJsonUtils.pas, OJsonReadWrite.pas and OJsonUtf8ReadWrite.pas - Added OnProgress event handlers to OXmlCDOM.pas and OXmlPDOM.pas - Lazarus 1.2/FPC 2.x compatibility issues solved - OXmlRTTISerialize.pas: splitted TCustomXMLRTTISerDes.Visibility into ObjectVisibility and RecordVisibility. - OXmlSerialize.pas: added support for TStrings. - Added TXMLNode.NodePath property (OXmlCDOM.pas, OXmlPDOM.pas). - Added TXMLDeserializer.ErrorHandling property (OXmlSerialize.pas). - Added TXMLRTTIDeserializer.ErrorHandling property (OXmlRTTISerialize.pas). - Added TXMLDeserializeErrorHandling.dehIgnore - OXmlSerialize: added support for SerDes of TCollection and TStrings when used as root object. - OXmlCDOM: added TXMLNode.NodePath property - Fixed xml and xmlns namespaces. They cannot be defined in an XML document. - With this change, OXml should be able to be used as vendor for SOAP in Delphi. - Fixed setting the xmlns attribute with SetAttributeNS. - Added TSAXParser.WhiteSpaceHandling - Fixed Delphi 2005 compilation Version 1.8 2015-05-28 [SVN commit: 86, https://sourceforge.net/p/oxml/code/86/] - Added OXmlCSeq.pas (sequential parser based on OXmlCDOM). ! File OXmlSeq.pas renamed to OXmlPSeq.pas to have te same format with OXmlPDOM. - Added TXMLNode.CloneNode with an IXMLDocument overloaded parameter. - ISOFloatToStr for Delphi 6 fixed. - Fixed bug in TSAXParser.OnXMLDeclaration. - Delphi XE7 packages recreated. - Delphi XE8 packages recreated. Version 1.7 2015-04-28 [SVN commit: 76, https://sourceforge.net/p/oxml/code/76/] - Compatibility with XE8. - Fixed FileList demo. - Completely rewritten TOVirtualHashIndex -> it's called TOVirtualHashedStrings now and it has the same properties as TOHashedStrings. - TOHashedStrings with object dictionary split into TOHashedStringObjDictionary. You can now use Pointer dictionary on ARC as well. - Fixed various bugs on NextGEN/ARC (OJSON.pas, OTextReadWrite.pas, OXmlCDOM.pas, OXmlPDOM.pas, OXmlReadWrite.pas, OXmlRTTISerialize.pas). - Unit tests now sucessfully run on all supported Delphi versions, including non-unicode, unicode, ARC and FPC/Lazarus. - Added more properties to TOBufferedWriteStream. - Added TOHashedStrings.OwnsObjects - Added a setter to TXMLNode.NodeName and TXMLNode.NodeNameId (OXmlPDOM, OXmlCDOM). - Added TSAXParser.OnXMLDeclaration - Fixed bug in WideStringReplace - Fixed demos - C++ Builder compatibility. - TOTextBuffer inserted back. - Delphi packages changed with use of LIBSUFFIX. OXml.dpk is a runtime package, OXml_Designtime.dpk is a design-time package. Version 1.6 2015-03-25 [SVN commit: 64, https://sourceforge.net/p/oxml/code/64/] - Added JSON reader/writer (beta). - Compatibility with FPC trunk (3.1.1). - Generics disabled in Delphi 2009 due to Delphi bugs. Version 1.5 2015-01-07 [SVN commit: 60, https://sourceforge.net/p/oxml/code/60/] - TEncoding.GetSupportedEncodings modified to a function. - Fixed bug in TEncoding in Delphi 2009 and 2010. - Some Delphi 5 issues solved. Version 1.4 2014-12-10 [SVN commit: 58, https://sourceforge.net/p/oxml/code/58/] - Fixed bug in TOWideStringList (only Delphi 5-2007). - OEncoding.pas: added support for Big Endian UTF-16. - OEncoding.pas: added support for UTF-7 (only Delphi 2009+ or Windows platform). - OXmlSerialize.pas: added support for TCollection. - OXmlRTTISerialize.pas: added support for TCollection. - Small bug in TXMLWriterElement fixed. Version 1.3 2014-12-04 [SVN commit: 57, https://sourceforge.net/p/oxml/code/57/] - Case-insensitive TOHashedStrings. - Fixed bug when reading file with last #10 character. - Fixed bug when reading entity (this invalid entity can be read only with StrictXML = False). Version 1.2 2014-11-20 [SVN commit: 56, https://sourceforge.net/p/oxml/code/56/] - SelectNodeCreate can handle a whole path now. E.g. "element1/element2/@attribute". - Added the aToDocument parameter to TXMLNode.CloneNode. - Default line break handling of the writer changed! Now WriterSettings.LineBreak is lbLF to comply with XML standards. The functions SaveToXML use always the system line breaks. - Fixed bug in ISOTryStrToBool. - TXMLNode.AbsolutePath and TXMLNode.NodeLevel properties added. - Resolved bugs in Delphi 2009-XE. - Faster ISOStrToFloat and ISOFloatToStr functions, they are still thread-safe. - FPC writer optimalizations. - ORealWideString renamed to OUnicodeString - Characters that are not in the target encoding are written as XML entities to the file. Works only for text nodes, cdata and attribute values. - Fixed bug in OXmlSerialize.pas - Removed UseIndex property from TXMLDeserializer and TXMLRTTIDeserializer (not used any more). - Added XML declaration and encoding support to TXMLSerializer and TXMLRTTISerializer. - Added TXMLNode.SortChildNodes, SortAttributeNodes, SortChildNodesByName, SortAttributeNodesByName - Added TXMLSerializer.UseRoot and TXMLDeserializer.UseRoot + more options/attributes in WriteObject and ReadObject (ReadObjectFromNode) - Added TXMLRTTISerializer.UseRoot and TXMLRTTISerializer.UseRoot + more options/attributes in WriteObject and ReadObject (ReadObjectFromNode) - Fixed bug in TXMLReader.NodePathAsString - RTTI serializer - added TObject in records support. - RTTI serializer generic record support. - OXmlPDOM and OXmlCDOM - added TXMLNode.FindChildWithIndex* functions for fast searching within ChildNodes. - Added TSerializableObjectDictionary. - Added TSerializableDictionary. Version 1.1 2014-09-24 [SVN commit: 33, https://sourceforge.net/p/oxml/code/33/] - Added OXmlSerialize.pas and OXmlRTTISerialize.pas - XML serializers - Added Delphi XE7 packages ! because some of the OXml backend files are now part of the Delphi RTL and they have the same filenames, you cannot install the design-time package in XE7 any more. I am solving this issue with Embarcadero now.
Contact me for more information (you can write in czech/english/german/russian):