2.9 (2020/07/23)

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:

OJson extension features:

OXml DataBinding extension features:

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() When using OXmlPDOM you should call TXMLNode.DeleteChild(), TXMLNode.DeleteAttribute() or TXMLNode.DeleteSelf in order to be sure the node memory is marked as free and can be reused again. 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 optimizations The 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') OXml features 7 classes/units for working with XML documents:OXml offers the same functionality as OmniXML but some functions/properties may have different names. The following table lists them:

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. 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, '

', [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 ***** OXml is available under commercial license.

Performance The following performance test can be found in the DEMO application and you can run it for yourself. 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").

The file is encoded in UTF-8, it's size is about 5,6 MB and node count (including attribute nodes) is 700'000. 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").

The file is encoded in UTF-8, it's size is about 11 MB and node count (including attribute nodes) is 900'000. 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 Download OXml TRIAL with demo applications for Delphi: 2.9 (oxml-trial-2-9--2020-07-23.zip) Installation OXml is a runtime library. Just add the source code directory to your Delphi library path. Please be sure you check the license information before downloading any of the files below.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 400,- (~ USD 450,-) OXml + DataBinding + OJson

for max. 3 developers within one company

+ 2 years of updates EUR 800,- (~ USD 900,-) OXml + DataBinding + OJson

for max. 5 developers within one company

+ 2 years of updates EUR 1200,- (~ USD 1350,-) OXml + DataBinding + OJson

for unlimited developers within one company

+ 2 years of updates EUR 1600,- (~ USD 1800,-) 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 125,- (~ USD 140,-) OXml

for max. 3 developers within one company

+ 2 years of updates EUR 250,- (~ USD 280,-) OXml

for max. 5 developers within one company

+ 2 years of updates EUR 375,- (~ USD 420,-) OXml

for unlimited developers within one company

+ 2 years of updates EUR 500,- (~ USD 560,-) 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 200,- (~ USD 225,-) OXml + OJson

for max. 3 developers within one company

+ 2 years of updates EUR 400,- (~ USD 450,-) OXml + OJson

for max. 5 developers within one company

+ 2 years of updates EUR 600,- (~ USD 675,-) OXml + OJson

for unlimited developers within one company

+ 2 years of updates EUR 800,- (~ USD 900,-)