I've done that in a generator thing I've made at work, using plain
XMLReader factory (code is off course employers property - but I can
outline the solution)
Problem: you have a string of xml that you need to generate SAX events
from, the string could be anything like:
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<tag>aklsks</tag>",
"<tag>aslkfkls</tag><tag>laskklfsa</tag>,
"<tag> aasdflaskj<kkk>fl</kkk>sadkjf </tag>"
The first string is a valid xml document, the second is missing the
xml-declaration and does not have a single toplevel element, the third one
is just missing the xml-declaration (does this actually make it an invalid
xml?)
Fixing the missing xml declaration can be done by:
if (!xmlstring.startsWith("<?xml")) {
xmlstring = "<?xml encoding=\"iso-8859-1\" version=\"1.0\" ?>" +
xmlstring;
}
Now if the xmlstring does contain the xml-declaration I would presume it
is a valid xml document with one top-level element, else I add a toplevel
element to be sure to have just one, thus fixing both the xml declaration
and the possible multiple toplevel elements is done by:
if (!xmlstring.startsWith("<?xml")) {
xmlstring = "<?xml encoding=\"iso-8859-1\" version=\"1.0\" ?><dummy>" +
xmlstring + "</dummy>";
}
When streaming the SAX Events I will later filter out the toplevel element
again ;-)
To be able to stream all but the toplevel element, you need a custom
ContentHandler; it should proxy all events but the startElement and
endElement of the toplevel tag; I've implemented it in an inner class and
it goes like:
protected class FilterContentHandler
implements ContentHandler
{
private ContentHandler destination;
private int depth = 0;
public FilterContentHandler (ContentHandler adestination)
{
destination = adestination;
}
public void startDocument ()
{
depth = 0;
}
public void endDocument ()
{
}
public void startElement (....)
{
if (depth > 0) {
destination.startElement (...)
}
depth++;
}
public void endElement (...)
{
depth--;
if (depth > 0) {
destination.endElement (...);
}
}
.. and more methods
}
Off course all methods throw the SAXException - methods from the
ContentHandler interface not listed here just proxy to the destination
ContentHandler.
Then I instantiate an XMLReader, let contenthandler be the sink of your
SAX Events:
XMLReader reader = XMLReaderFactory.createXMLReader ();
reader.setContentHandler (new FilterContentHandler (contenthandler));
Make an inputsource:
InputSource inputsource =
new InputSource (new StringReader (xmlstring);
then just do:
reader.parse (inputsource);
If you need a better example I could spent some of my spare time making
it, maybe during the weekend.
Regards Jakob
Jakob Dalsgaard
Udvikler
e-mail: [EMAIL PROTECTED]
Vesterbrogade 149
1620 K�benhavn V
Tlf.: 70 25 80 30
Fax.: 70 25 80 31
"Luca Morandini" <[EMAIL PROTECTED]>
11/08/02 10:55 AM
Please respond to cocoon-users
To: <[EMAIL PROTECTED]>
cc:
Subject: Strings to SAX events
Folks,
We're in the process of writing a Transformer, which, of course, outputs
SAX
events... but, in the midst of this stream , we need to insert an
XML element stored in a string.
To do this we're groping in the dark trying something like this:
JaxpParser respParser = new JaxpParser();
respParser.parse( new InputSource(new StringReader(str)),
new EmbeddedXMLPipe(contentHandler));
Which fails giving this:
org.apache.cocoon.ProcessingException: Failed to execute pipeline.:
java.lang.ClassCastException
...
Caused by: java.lang.ClassCastException
at
com.lucamorandini.charts.ChartTransformer.endElement(ChartTransformer.java:6
55)
at
org.apache.cocoon.components.sax.XMLByteStreamInterpreter.parse(XMLByteStrea
mInterpreter.java:129)
at
org.apache.cocoon.components.sax.XMLByteStreamInterpreter.deserialize(XMLByt
eStreamInterpreter.java:102)
at
org.apache.cocoon.components.pipeline.CachingEventPipeline.process
(CachingEventPipeline.java:219)
... 44 more
java.lang.ClassCastException
at
com.lucamorandini.charts.ChartTransformer.endElement(ChartTransformer.java:6
55)
at
org.apache.cocoon.components.sax.XMLByteStreamInterpreter.parse(XMLByteStrea
mInterpreter.java:129)
at
org.apache.cocoon.components.sax.XMLByteStreamInterpreter.deserialize(XMLByt
eStreamInterpreter.java:102)
at
org.apache.cocoon.components.pipeline.CachingEventPipeline.process
(CachingEventPipeline.java:219)
at
org.apache.cocoon.components.pipeline.CachingStreamPipeline.process(CachingS
treamPipeline.java:399)
The classes we use are:
org.apache.avalon.excalibur.xml.JaxpParser;
org.xml.sax.InputSource;
java.io.StringReader;
org.apache.cocoon.xml.EmbeddedXMLPipe;
And the environment is:
Solaris 5.8
JDK 1.4.1_01
Tomcat 4.1.12-LE-jdk14
Cocoon 2.0.3
May someone please help us ?
Thanks in advance,
Piero De Nicola & Luca Morandini
We are protected from the virus by Norton Antivirus Corporate Edition
---------------------------------------------------------------------
Please check that your question has not already been answered in the
FAQ before posting. <http://xml.apache.org/cocoon/faq/index.html>
To unsubscribe, e-mail: <[EMAIL PROTECTED]>
For additional commands, e-mail: <[EMAIL PROTECTED]>
---------------------------------------------------------------------
Please check that your question has not already been answered in the
FAQ before posting. <http://xml.apache.org/cocoon/faq/index.html>
To unsubscribe, e-mail: <[EMAIL PROTECTED]>
For additional commands, e-mail: <[EMAIL PROTECTED]>