sample XSD fails with "error: no declaration found for element X"
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?
There are some options. The schema location can be provided in the file hello.xml:
<?xml version="1.0"?>
<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="hello.xsd">
<greeting>Hello</greeting>
<name>sun</name>
<name>moon</name>
<name>world</name>
</hello>
Another option is to provide the schema location in the file hello.c++
If we assume the schema file is located at the filepath /some/file/path/hello.xsd
we should instead of writing
auto_ptr<hello_t> h (hello ("hello.xml"));
write
xml_schema::properties properties;
properties.no_namespace_schema_location("file:///some/file/path/hello.xsd");
auto_ptr<hello_t> h (hello ("hello.xml", 0, properties));
You can read more about this in the Codesynthesis FAQ:
Why do I get "error: no declaration found for element 'root-element'" when I try to parse a valid XML document?
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>
EDIT: Ignore this answer. I'm leaving it up because the comments are worth saving.
Your XSD says:
<xs:complexType name="hello_t">
but your XML says:
<hello>
...
</hello>
Perhaps the XSD should be:
<xs:complexType name="hello">
Also, the XML is missing an xsi:schemaLocation declaration. It might help to have one.
精彩评论