Discussion:
[XOM-interest] XOM + XInclude + XSLT Transform + EntityResolver
Thomas LEDUC
2010-06-15 19:10:18 UTC
Permalink
Dear list-members,

I would like to benefit from XOM recursive XInclude ability. That's why,
I've given XALAN up. With XALAN, I was able to combine a (single)
XInclude with an EntityResolver (the x-included XML was located in the
JAR file and activated as a ResourceStream trough an EntityResolver) and
a XSLT Transform.

What I want right now is tu use XOM so as to combine 2 or 3 levels of
recursive XInclude with an EntityResolver (so as to x-include the XML
located as resources in the JAR file) and a XSLT transform. To achieve
such an objective, I've tried to follow P. Taylor's intructions (thanks
to him) described in the following post :
http://lists.ibiblio.org/pipermail/xom-interest/2009-August/003977.html

To reproduce the process I want to do, I've developed the small use case
presented below. Unfortunately, the following independent class (that
replaces class.getResourceAsStream by ByteArrayInputStream : XML2 is
x-included in XML1) compiles but crashes during execution. Do you know
why ? What should I do to solve my bug ?

Many thanks for your help,

import java.io.*;
import javax.xml.parsers.SAXParserFactory;
import nu.xom.*;
import nu.xom.xinclude.XIncluder;
import nu.xom.xslt.XSLTransform;
import org.xml.sax.*;

public class MyXomTest {
private static final String XML1 = "<?xml version='1.0'><aa
xmlns:xi='http://www.w3.org/2001/XInclude'><xi:include
href='foo.xml'/><dd/></aa>";
private static final String XML2 = "<?xml version='1.0'?><bb><cc
name='foo'/></bb>";
private static final String XSLT_IDENTITY = "<?xml version='1.0'?>"
+ "<xsl:stylesheet version='1.0'
xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
+ "<xsl:template match='node()|@*'>" + "<xsl:copy>"
+ "<xsl:apply-templates select='@*|node()'/>" + "</xsl:copy>"
+ "</xsl:template>" + "</xsl:stylesheet>";

public static class MyEntityResolver implements EntityResolver {
@Override
public InputSource resolveEntity(String arg0, String arg1)
throws SAXException, IOException {
InputStream inputStream = new
ByteArrayInputStream(XML2.getBytes());
InputSource inputSource = new InputSource(inputStream);
inputSource.setSystemId(AConsoleCommand.USER_DIR);
return inputSource;
}
}

public static void main(String[] args) throws Exception {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
saxParserFactory.setXIncludeAware(true);
XMLReader x = saxParserFactory.newSAXParser().getXMLReader();
x.setEntityResolver(new MyEntityResolver());

Builder builder = new Builder(x);
Document input = builder
.build(new ByteArrayInputStream(XML1.getBytes()));
Document intermed_result = XIncluder.resolve(input, builder);
Document stylesheet = builder.build(new ByteArrayInputStream(
XSLT_IDENTITY.getBytes()));
XSLTransform transform = new XSLTransform(stylesheet);
Nodes output = transform.transform(intermed_result);
Document result = XSLTransform.toDocument(output);
System.out.println(result.toXML());
}
}
Michael Kay
2010-06-15 19:46:55 UTC
Permalink
Post by Thomas LEDUC
What should I do to solve my bug ?
Examine the stack trace. If you don't understand it, post it here, where there's a good chance that someone will.

Michael Kay
Saxonica
Post by Thomas LEDUC
Dear list-members,
I would like to benefit from XOM recursive XInclude ability. That's why,
I've given XALAN up. With XALAN, I was able to combine a (single)
XInclude with an EntityResolver (the x-included XML was located in the
JAR file and activated as a ResourceStream trough an EntityResolver) and
a XSLT Transform.
What I want right now is tu use XOM so as to combine 2 or 3 levels of
recursive XInclude with an EntityResolver (so as to x-include the XML
located as resources in the JAR file) and a XSLT transform. To achieve
such an objective, I've tried to follow P. Taylor's intructions (thanks
http://lists.ibiblio.org/pipermail/xom-interest/2009-August/003977.html
To reproduce the process I want to do, I've developed the small use case
presented below. Unfortunately, the following independent class (that
replaces class.getResourceAsStream by ByteArrayInputStream : XML2 is
x-included in XML1) compiles but crashes during execution. Do you know
why ? What should I do to solve my bug ?
Many thanks for your help,
import java.io.*;
import javax.xml.parsers.SAXParserFactory;
import nu.xom.*;
import nu.xom.xinclude.XIncluder;
import nu.xom.xslt.XSLTransform;
import org.xml.sax.*;
public class MyXomTest {
private static final String XML1 = "<?xml version='1.0'><aa
xmlns:xi='http://www.w3.org/2001/XInclude'><xi:include
href='foo.xml'/><dd/></aa>";
private static final String XML2 = "<?xml version='1.0'?><bb><cc
name='foo'/></bb>";
private static final String XSLT_IDENTITY = "<?xml version='1.0'?>"
+ "<xsl:stylesheet version='1.0'
xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
+ "</xsl:template>" +"</xsl:stylesheet>";
public static class MyEntityResolver implements EntityResolver {
@Override
public InputSource resolveEntity(String arg0, String arg1)
throws SAXException, IOException {
InputStream inputStream = new
ByteArrayInputStream(XML2.getBytes());
InputSource inputSource = new InputSource(inputStream);
inputSource.setSystemId(AConsoleCommand.USER_DIR);
return inputSource;
}
}
public static void main(String[] args) throws Exception {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
saxParserFactory.setXIncludeAware(true);
XMLReader x = saxParserFactory.newSAXParser().getXMLReader();
x.setEntityResolver(new MyEntityResolver());
Builder builder = new Builder(x);
Document input = builder
.build(new ByteArrayInputStream(XML1.getBytes()));
Document intermed_result = XIncluder.resolve(input, builder);
Document stylesheet = builder.build(new ByteArrayInputStream(
XSLT_IDENTITY.getBytes()));
XSLTransform transform = new XSLTransform(stylesheet);
Nodes output = transform.transform(intermed_result);
Document result = XSLTransform.toDocument(output);
System.out.println(result.toXML());
}
}
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
Thomas LEDUC
2010-06-16 09:56:00 UTC
Permalink
Post by Michael Kay
Post by Thomas LEDUC
What should I do to solve my bug ?
Examine the stack trace. If you don't understand it, post it here, where there's a good chance that someone will.
Michael Kay
Saxonica
Dear Michael,
Thanks for your answer. Is the following trace the right one ?

[Fatal Error] :1:20: A pseudo attribute name is expected.
Exception in thread "main" nu.xom.ParsingException: A pseudo attribute
name is expected. at line 1, column 20
at nu.xom.Builder.build(Unknown Source)
at nu.xom.Builder.build(Unknown Source)
at org.solenetb.engine.MyXomTest.main(MyXomTest.java:39)
Caused by: org.xml.sax.SAXParseException: A pseudo attribute name is
expected.
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
Source)
... 3 more
Michael Kay
2010-06-16 10:39:48 UTC
Permalink
The fact that it's a ParsingException is a pretty good clue that there's
something wrong with the XML, and the fact that it's on line

MyXomTest.java:39

should tell you whether it's complaining about the source document or
the stylesheet. (I can't tell myself, because the mailer has reformatted
the Java code).

"Pseudo attributes" generally occur in processing instructions or the
like, and peering at the XML more closely reveals

<?xml version='1.0'>

which should be

<?xml version='1.0'?>

There's a lot of information in the diagnostics for this kind of
problem; it's worth learning to read them, and it's certainly worth
posting them if you want help understanding what's gone wrong.

Michael Kay
Saxonica
Post by Thomas LEDUC
Post by Michael Kay
Post by Thomas LEDUC
What should I do to solve my bug ?
Examine the stack trace. If you don't understand it, post it here, where there's a good chance that someone will.
Michael Kay
Saxonica
Dear Michael,
Thanks for your answer. Is the following trace the right one ?
[Fatal Error] :1:20: A pseudo attribute name is expected.
Exception in thread "main" nu.xom.ParsingException: A pseudo attribute
name is expected. at line 1, column 20
at nu.xom.Builder.build(Unknown Source)
at nu.xom.Builder.build(Unknown Source)
at org.solenetb.engine.MyXomTest.main(MyXomTest.java:39)
Caused by: org.xml.sax.SAXParseException: A pseudo attribute name is
expected.
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
Source)
... 3 more
_______________________________________________
XOM-interest mailing list
XOM-interest at lists.ibiblio.org
http://lists.ibiblio.org/mailman/listinfo/xom-interest
Thomas LEDUC
2010-06-16 15:14:49 UTC
Permalink
Post by Michael Kay
The fact that it's a ParsingException is a pretty good clue that there's
something wrong with the XML, and the fact that it's on line
MyXomTest.java:39
[...]
which should be
<?xml version='1.0'?>
Many thanks Michael, yes indeed, it was a syntax error.

Contrarily to what I wrote yesterday, I'm unable to process recursive
X-include. I've modified a bit the use case I sent so as to attest it
(see the independent class below). Here is the crash trace:

[Fatal Error] engine:1:1: Recursive include detected. Document
'file:///home/leduc/solenetb/trunk/platform/engine' was already processed.
[Fatal Error] engine:1:115: Error attempting to parse XML file
(href='lvl_2.xml').
[Fatal Error] :1:99: Error attempting to parse XML file (href='lvl_1.xml').
Exception in thread "main" nu.xom.ParsingException: Error attempting to
parse XML file (href='lvl_1.xml'). at line 1, column 99
at nu.xom.Builder.build(Unknown Source)
at nu.xom.Builder.build(Unknown Source)
at org.solenetb.engine.MyXomTest.main(MyXomTest.java:49)
Caused by: org.xml.sax.SAXParseException: Error attempting to parse XML
file (href='lvl_1.xml').
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown
Source)
... 3 more

And the class content:

import java.io.*;

import javax.xml.parsers.SAXParserFactory;
import nu.xom.*;
import nu.xom.xinclude.XIncluder;
import nu.xom.xslt.XSLTransform;
import org.xml.sax.*;

public class MyXomTest {
private static final String XML1 = "<?xml version='1.0'?><aa
xmlns:xi='http://www.w3.org/2001/XInclude'><xi:include
href='lvl_1.xml'/><dd/></aa>";
private static final String XML2 = "<?xml version='1.0'?><bb
xmlns:xi='http://www.w3.org/2001/XInclude'><cc name='foo'/><xi:include
href='lvl_2.xml'/></bb>";
private static final String XML3 = "<?xml version='1.0'?><bb><cc
name='foo'/></bb>";
private static final String XSLT_IDENTITY = "<?xml version='1.0'?>"
+ "<xsl:stylesheet version='1.0'
xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
+ "<xsl:template match='node()|@*'>" + "<xsl:copy>"
+ "<xsl:apply-templates select='@*|node()'/>" + "</xsl:copy>"
+ "</xsl:template>" + "</xsl:stylesheet>";

public static class MyEntityResolver implements EntityResolver {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
InputStream inputStream = null;
if (systemId.endsWith("lvl_1.xml")) {
inputStream = new ByteArrayInputStream(XML2.getBytes());
} else if (systemId.endsWith("lvl_2.xml")) {
inputStream = new ByteArrayInputStream(XML3.getBytes());
}
if (null == inputStream) {
return null;
}
InputSource inputSource = new InputSource(inputStream);
inputSource.setSystemId(AConsoleCommand.USER_DIR);
return inputSource;
}
}

public static void main(String[] args) throws Exception {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
saxParserFactory.setXIncludeAware(true);
XMLReader x = saxParserFactory.newSAXParser().getXMLReader();
x.setEntityResolver(new MyEntityResolver());

Builder builder = new Builder(x);
Document input = builder
.build(new ByteArrayInputStream(XML1.getBytes()));
Document intermed_result = XIncluder.resolve(input, builder);
Document stylesheet = builder.build(new ByteArrayInputStream(
XSLT_IDENTITY.getBytes()));
XSLTransform transform = new XSLTransform(stylesheet);
Nodes output = transform.transform(intermed_result);
Document result = XSLTransform.toDocument(output);
System.out.println(result.toXML());
}
}

Loading...