In spite of being a total newbie in the xml parsing arena, I was able to xsd
to create valid c++
and compile and link successfully, but the compiler optimized(?) away the instantiation. So, starting at step one, I try the hello world xml example at CodeSynthesis. But that fails:
[wally@lenovotower xml]$ make hello
xsdcxx cxx-tree hello.xsd
g++ -c -o helloschema.o hello.cxx
g++ -g -o hello -lxerces-c helloschema.o hello.c++
[wally@lenovotower xml]$ ./hello
hello.xml:2:8 error: no declaration found for element 'hello'
hello.xml:4:13 error: no declaration found for element 'greeting'
hello.xml:6:9 error: no declaration found for element 'name'
hello.xml:7:9 error: no declaration found for element 'name'
hello.xml:8:9 error: no declaration found for element 'name'
hello.c++:
#include <iostream>
#include <stdio.h>
#include "hello.hxx"
using namespace std;
int main (void)
{
try {
auto_ptr<hello_t> h (hello ("hello.xml"));
for (hello_t::name_const_iterator i (h->name ().begin());
i != h->name().end();
++i)
cout << h->greeting () << ", " << *i << "!" << endl;
}
catch (const xml_schema::exception& e)
{
cerr << e << endl;
return 1;
}
return 0;
}
hello.xml:
<?xml version="1.0"?>
<hello>
<greeting>Hello</greeting>
<name>sun</name>
<name>moon</name>
<name>world</name>
</hello>
hello.xsd:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="hello_t">
<xs:sequence>
<xs:element name="greeting" type="xs:string"/>
<xs:element name="name" type="xs:string" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="hello" type="hello_t"/>
</xs:schema>
I think this is exactly what it says to do, but the commands don't work exactly as documented. I discovered xsdcxx
seems to do the right thing (unlike xsd
which generates C# or vb.net output).
[wally@lenovotower xml]$ xsdcxx --version
CodeSynthesis XSD XML Schema to C++ compiler 3.3.0
Copyright (C) 2005-2010 Code Synthesis Tools CC
Also, I don't include an -I
(dir) and it compiles happily. Could it be using the wrong include file somehow?
What am I doing wrong? Maybe xsd
isn't the right tool?
Personally I find the combination of Python and lxml to be pretty invaluable. Your XML document and the corresponding XML schema work just fine:
from lxml import etree
xsddoc = etree.parse('hello.xsd')
xsd = etree.XMLSchema(xsddoc)
xml_parser = etree.XMLParser(schema=xsd)
xmldoc = etree.parse('hello.xml', parser=xml_parser)
I didn't get any errors from that. I will say, however, that even though lxml doesn't require you to use xsi:noNamespaceSchemaLocation since it loads the schema you specify, you should still use it as long as you're not using namespaces. Just because one XML parser is flexible, others might not be, a fact that it seems you might have figured out the hard way. If you do use namespaces, use xsi:schemaLocation instead of xsi:noNamespaceSchemaLocation. Also note that you MUST declare the xsi namespace via the xmlns:xsi attribute to be able to use the xsi:* attributes.
An example using xsi:noNamespaceSchemaLocation:
<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="hello.xsd">
...
</hello>