[lxml-dev] etree.Element from RNG schema?
Can lxml give me back an Element object from a parsed RNG schema? That is, given parser = etree.RelaxNG(etree.parse(file("foo.rng"))) I'd like to do something like parser.getroot() in order to get back an Element/ElementTree which is like the original schema except with grammar/define's expanded. What I want is to go from <grammar> <start> <element name="foo"> <ref name="bar" /> </element> </start> <define name="bar"> <text /> </define> </grammar> to <element name="foo"> <text /> </element> I realize this can't be done in all cases, e.g. there's no way to express recursive references outside of a <grammar>. But in that case lxml could return an error, or simply not recurse (so the expanded element tree would contain the <ref> itself). But even without handling recursion, wow it would be valuable for me not to have to chase down includes and externalRef's, and more so not to have to [re]implement combine rules. -frank
Hi, Frank Cusack wrote:
Can lxml give me back an Element object from a parsed RNG schema? That is, given
parser = etree.RelaxNG(etree.parse(file("foo.rng")))
I'd like to do something like parser.getroot() in order to get back an Element/ElementTree which is like the original schema except with grammar/define's expanded.
What I want is to go from
<grammar> <start> <element name="foo"> <ref name="bar" /> </element> </start>
<define name="bar"> <text /> </define> </grammar>
to
<element name="foo"> <text /> </element>
libxml2 does not expose the internals of its schemas (RNG/XSD). But if all you want is resolved <ref> tags, you can do that yourself very easily, without passing through RelaxNG at all. (You might want to use .iter(tag) for that instead of XPath, BTW). Stefan
On July 17, 2008 7:03:40 AM +0200 Stefan Behnel <stefan_ml@behnel.de> wrote:
But if all you want is resolved <ref> tags, you can do that yourself very easily, without passing through RelaxNG at all. (You might want to use .iter(tag) for that instead of XPath, BTW).
Not sure I'd agree with "very easily". You have to handle include, externalRef, recursion and combination. I'll look at .iter(), thanks. -frank
Hi, Frank Cusack wrote:
On July 17, 2008 7:03:40 AM +0200 Stefan Behnel wrote:
But if all you want is resolved <ref> tags, you can do that yourself very easily, without passing through RelaxNG at all. (You might want to use .iter(tag) for that instead of XPath, BTW).
Not sure I'd agree with "very easily". You have to handle include, externalRef, recursion and combination.
Yes, that's cumbersome. Especially if you know the code is already there, but you can't get to the result...
I'll look at .iter(), thanks.
Yes, .iter(tag) is really fast. Even multiple loops over .iter(tag) can still be faster than an or-ed XPath expression for multiple tags. Also take a look at ElementInclude.py, which implements (almost) XInclude in pure Python, and at relaxng.c in libxml2, which implements the whole algorithm after all. A good test is creating a RelaxNG object before and after running the schema through your own include etc. handler, and then validate a set of XML documents with both to compare the result. If you can come up with a pure Python implementation of this, I'm sure there will be others who are interested, so please report back and consider submitting an implementation. Stefan
On July 18, 2008 8:25:44 AM +0200 Stefan Behnel <stefan_ml@behnel.de> wrote:
Also take a look at ElementInclude.py, which implements (almost) XInclude in pure Python, and at relaxng.c in libxml2, which implements the whole algorithm after all.
A good test is creating a RelaxNG object before and after running the schema through your own include etc. handler, and then validate a set of XML documents with both to compare the result.
If you can come up with a pure Python implementation of this, I'm sure there will be others who are interested, so please report back and consider submitting an implementation.
My preference would be to change libxml2 to export the fully parsed schema, and then it's a simple matter for lxml to pick it up. I'll look into it. -frank
participants (2)
-
Frank Cusack -
Stefan Behnel