Difference between revisions of "GnuCash XML format"

From GnuCash
Jump to: navigation, search
(updated and corrected)
(Add schema note)
Line 1: Line 1:
 
This article collects some notes about the XML file format of [[GnuCash]]. So far it is just descriptive, and neither normative nor authoritative.  
 
This article collects some notes about the XML file format of [[GnuCash]]. So far it is just descriptive, and neither normative nor authoritative.  
  
Beginning with version 1.6, the primary GnuCash storage mechanism is an [[Wikipedia:XML|XML]] file.  The file is optionally compressed with [[Wikipedia:gzip|gzip]] (“<u>E</u>dit” menu → “Preferences” → “General” → “Use file compression”). The schema of the XML document is not presently defined declaratively (e.g. by [[Document Type Definition]] or [[XML Schema]]). Some old, outdated DTDs exist in SVN in src/doc/xml/, but the current file format is slightly different. <!-- or does QOF use some kind of declarative schema? -->
+
Beginning with version 1.6, the primary GnuCash storage mechanism is an [[Wikipedia:XML|XML]] file.  The file is optionally compressed with [[Wikipedia:gzip|gzip]] (“<u>E</u>dit” menu → “Preferences” → “General” → “Use file compression”).
 +
 
 +
There is a non-normative schema for the 1.8/2.0 XML file format at http://svn.gnucash.org/trac/browser/gnucash/trunk/src/doc/xml/gnucash-v2.rnc.
  
 
Please keep in mind that GnuCash series 1.8.x uses the libxml1 library for XML access, whereas 1.9.0 and later uses the libxml2 library. Some behaviour regarding XML files is therefore quite different in 1.8.x compared to 1.9.x/2.0.0.
 
Please keep in mind that GnuCash series 1.8.x uses the libxml1 library for XML access, whereas 1.9.0 and later uses the libxml2 library. Some behaviour regarding XML files is therefore quite different in 1.8.x compared to 1.9.x/2.0.0.
Line 56: Line 58:
 
==External links==
 
==External links==
 
* http://qof.sourceforge.net/ - QOF is the object persistence layer used by GnuCash
 
* http://qof.sourceforge.net/ - QOF is the object persistence layer used by GnuCash
 +
** [[User:Jsled]] That's slightly misleading in the context of this page; for instance, when writing out the data to the current XML format, QOF isn't used at all.
 
* http://gnucashtoqif.sourceforge.net/ - GnuCash XML &rarr; [[Wikipedia:QIF|QIF]] conversion tool
 
* http://gnucashtoqif.sourceforge.net/ - GnuCash XML &rarr; [[Wikipedia:QIF|QIF]] conversion tool
 
** [http://gnucashtoqif.sourceforge.net/#mozTocId164261 notes about file format]
 
** [http://gnucashtoqif.sourceforge.net/#mozTocId164261 notes about file format]

Revision as of 13:03, 24 February 2006

This article collects some notes about the XML file format of GnuCash. So far it is just descriptive, and neither normative nor authoritative.

Beginning with version 1.6, the primary GnuCash storage mechanism is an XML file. The file is optionally compressed with gzip (“Edit” menu → “Preferences” → “General” → “Use file compression”).

There is a non-normative schema for the 1.8/2.0 XML file format at http://svn.gnucash.org/trac/browser/gnucash/trunk/src/doc/xml/gnucash-v2.rnc.

Please keep in mind that GnuCash series 1.8.x uses the libxml1 library for XML access, whereas 1.9.0 and later uses the libxml2 library. Some behaviour regarding XML files is therefore quite different in 1.8.x compared to 1.9.x/2.0.0.

In all XML files written by a 1.8.x version, XML files created by GnuCash are missing XML namespace declarations that are required by some XML processing software (see also FAQ#Q: How can I export data?). See GnuCash Tutorial and Concepts Guide, Appendix A, part 5: Converting XML GnuCash File for the missing declarations. From version 1.8.5 onwards GnuCash is able to read XML files containing these declarations [1]. From 1.9.0 onwards GnuCash will write the required namespace declarations as well.

Character encoding

GnuCash 1.8.x interprets XML documents using a character encoding determined by operating-system–level locale settings, and so does not include an encoding declaration in the opening XML text declaration. (The locale setting here constitues a “higher-level protocol” in W3C vernacular [2].) GnuCash serializes non-ASCII octets (i.e. those with the high-order bit set) as decimal numeric entity references.

On the other hand, GnuCash 1.9.0 and later writes the XML document always in UTF-8 encoding and also includes the appropriate encoding declaration in the opening XML text declaration. (I think the serialization is still done as decimal numeric entities but this has to be checked.)

For example, in 1.8.x the UTF-8 encoding of the Cyrillic capital letter “Б” is written as “&#208;&#145;”. As the following Python script shows, the UTF-8 text should be transcoded to recover the original Unicode text. (This script uses the 4Suite XML library.)

#! /usr/bin/python2.4                                                                                                                               

from Ft.Xml.Domlette import NonvalidatingReader
from Ft.Xml.XPath import Evaluate
from Ft.Xml.XPath.Context import Context

# precondition: foo.xac was created by GnuCash with LANG=en_US.UTF-8
doc = NonvalidatingReader.parseUri('file:///tmp/foo.xac')
context = Context(doc, processorNss={'cd'    : "http://www.gnucash.org/XML/cd",
                                     'book'  : "http://www.gnucash.org/XML/book",
                                     'gnc'   : "http://www.gnucash.org/XML/gnc",
                                     'cmdty' : "http://www.gnucash.org/XML/cmdty",
                                     'trn'   : "http://www.gnucash.org/XML/trn",
                                     'split' : "http://www.gnucash.org/XML/split",
                                     'act'   : "http://www.gnucash.org/XML/act",
                                     'price' : "http://www.gnucash.org/XML/price",
                                     'ts'    : "http://www.gnucash.org/XML/ts",
                                     'slot'  : "http://www.gnucash.org/XML/kvpslot",
                                     'cust'  : "http://www.gnucash.org/XML/cust",
                                     'addr'  : "http://www.gnucash.org/XML/custaddr"})

accountName = Evaluate('/gnc-v2/gnc:book/gnc:account[act:id="0d69c3557f4d9340198bfd151f9e13cb"]/act:name/text()',
                       context=context)[0]

# object of type "str" (is actually UTF-8–encoded, not latin1!):                                                                                                                         
name_raw = accountName.data.encode('latin1')

# object of type "unicode":
name_unicode = name_raw.decode('utf-8')

# objects of type "str":                                                                                                                            
name_koi8r = name_unicode.encode('koi8-r')
name_utf8  = name_unicode.encode('utf-8')
name_utf16 = name_unicode.encode('utf-16')

assert name_utf8 == accountName.data.encode('latin1')

See also

External links