You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Glen Daniels <gl...@thoughtcraft.com> on 2005/08/29 21:38:17 UTC

[axis2] Writing an empty element?

Anyone have a clue if there is a way to use the XMLStreamWriter to get:

<elem attr="1"/>

instead of:

<elem attr="1"></elem>

for elements with attributes but no content?

If not, this seems VERY BAD.

Here is some code:

         String xml = "<test attr='foo'><check/></test>";
         ByteArrayInputStream bis = new 
ByteArrayInputStream(xml.getBytes());
         XMLStreamReader reader = 
XMLInputFactory.newInstance().createXMLStreamReader(bis);
         OMXMLParserWrapper builder = 
OMXMLBuilderFactory.createStAXOMBuilder(OMAbstractFactory.getSOAP11Factory(), 
reader);
         XMLStreamWriter writer = 
XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
         builder.getDocumentElement().serialize(writer);

NOTE - to get this working I needed to update StreamingOMSerializer:137 
with:

             writer.writeStartElement(reader.getLocalName());

This code outputs:

<test attr="foo"><check xmlns=""></check></test>

This doesn't seem correct.  It should, I think, output the <check/> 
element as it is in the original XML, and it certainly shouldn't be 
adding the xmlns="" attribute.  Am I missing something?

Thanks,
--Glen

Re: [stax_builders] Re: [axis2] Writing an empty element?

Posted by Aleksander Slominski <as...@cs.indiana.edu>.
Aleksander Slominski wrote:

>Dennis Sosnoski wrote:
>
>  
>
>>Aleksander Slominski wrote:
>>
>>    
>>
>>>please pull StAX RI from SVN (http://stax.codehaus.org/Home) and 
>>>build jar file (ant).
>>>
>>>then if you run test program (below) it should be producing this:
>>>
>>>Created not using repairing :-
>>><?xml version='1.0' encoding='utf-8'?><env:Envelope 
>>>xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
>>>xmlns:test="http://someTestUri"><env:Body><test foo="bar"/><test 
>>>foo="bar"></test><test foo="bar"> </test></env:Body></env:Envelope>
>>>Created  using repairing :-
>>><?xml version='1.0' encoding='utf-8'?><env:Envelope 
>>>xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
>>>xmlns:test="http://someTestUri" xmlns:test="http://someTestUri" 
>>>xmlns:env="http://www.w3.org/2003/05/soap-envelope"><env:Body><test 
>>>foo="bar"/><test foo="bar"></test><test foo="bar"> 
>>></test></env:Body></env:Envelope>
>>>
>>>      
>>>
>>Maybe I missed something in this exchange, Alex, but the second 
>>(repairing) version appears to be bad XML - the xmlns:test 
>>attribute/namespace declaration appears twice on the env:Envelope 
>>start tag.
>>    
>>
>
>there is a long standing bug in a way StAX under-specified "namespace 
>repairing" feature is implemented in RI (it is amazing how 
>complex/incomplete this feature is considering how simple and 
>essentially bullet-proof XmlPull::XmlSerializer is -  it looked good on 
>paper to have  "repairing namespace", oh well ...) - and fixing it is 
>not fun as XMLWriterBase is anything but simple - i just wasted some 
>time trying to grasp inner working of XMLWriterBase ...
>
>  
>
for now it is fixed: 
http://www.extreme.indiana.edu/bugzilla/show_bug.cgi?id=208

after i run test program i get:

Created not using repairing :-
<?xml version='1.0' encoding='utf-8'?><env:Envelope 
xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
xmlns:test="http://someTestUri"/>
Created  using repairing :-
<?xml version='1.0' encoding='utf-8'?><env:Envelope 
xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
xmlns:test="http://someTestUri"/>

and for empty elem:

Created not using repairing :-
<?xml version='1.0' encoding='utf-8'?><env:Envelope 
xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
xmlns:test="http://someTestUri"><env:Body><test foo="bar"/><test 
foo="bar"></test><test foo="bar"> </test></env:Body></env:Envelope>
Created  using repairing :-
<?xml version='1.0' encoding='utf-8'?><env:Envelope 
xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
xmlns:test="http://someTestUri"><env:Body><test foo="bar"/><test 
foo="bar"></test><test foo="bar"> </test></env:Body></env:Envelope>

so far so good ..

alek

-- 
The best way to predict the future is to invent it - Alan Kay


Re: [axis2] Writing an empty element?

Posted by Aleksander Slominski <as...@cs.indiana.edu>.
Dennis Sosnoski wrote:

> Aleksander Slominski wrote:
>
>>
>> please pull StAX RI from SVN (http://stax.codehaus.org/Home) and 
>> build jar file (ant).
>>
>> then if you run test program (below) it should be producing this:
>>
>> Created not using repairing :-
>> <?xml version='1.0' encoding='utf-8'?><env:Envelope 
>> xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
>> xmlns:test="http://someTestUri"><env:Body><test foo="bar"/><test 
>> foo="bar"></test><test foo="bar"> </test></env:Body></env:Envelope>
>> Created  using repairing :-
>> <?xml version='1.0' encoding='utf-8'?><env:Envelope 
>> xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
>> xmlns:test="http://someTestUri" xmlns:test="http://someTestUri" 
>> xmlns:env="http://www.w3.org/2003/05/soap-envelope"><env:Body><test 
>> foo="bar"/><test foo="bar"></test><test foo="bar"> 
>> </test></env:Body></env:Envelope>
>>
> Maybe I missed something in this exchange, Alex, but the second 
> (repairing) version appears to be bad XML - the xmlns:test 
> attribute/namespace declaration appears twice on the env:Envelope 
> start tag.

there is a long standing bug in a way StAX under-specified "namespace 
repairing" feature is implemented in RI (it is amazing how 
complex/incomplete this feature is considering how simple and 
essentially bullet-proof XmlPull::XmlSerializer is -  it looked good on 
paper to have  "repairing namespace", oh well ...) - and fixing it is 
not fun as XMLWriterBase is anything but simple - i just wasted some 
time trying to grasp inner working of XMLWriterBase ...

alek

-- 
The best way to predict the future is to invent it - Alan Kay


Re: [axis2] Writing an empty element?

Posted by Dennis Sosnoski <dm...@sosnoski.com>.
Aleksander Slominski wrote:

>
> please pull StAX RI from SVN (http://stax.codehaus.org/Home) and build 
> jar file (ant).
>
> then if you run test program (below) it should be producing this:
>
> Created not using repairing :-
> <?xml version='1.0' encoding='utf-8'?><env:Envelope 
> xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
> xmlns:test="http://someTestUri"><env:Body><test foo="bar"/><test 
> foo="bar"></test><test foo="bar"> </test></env:Body></env:Envelope>
> Created  using repairing :-
> <?xml version='1.0' encoding='utf-8'?><env:Envelope 
> xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
> xmlns:test="http://someTestUri" xmlns:test="http://someTestUri" 
> xmlns:env="http://www.w3.org/2003/05/soap-envelope"><env:Body><test 
> foo="bar"/><test foo="bar"></test><test foo="bar"> 
> </test></env:Body></env:Envelope>
>
Maybe I missed something in this exchange, Alex, but the second 
(repairing) version appears to be bad XML - the xmlns:test 
attribute/namespace declaration appears twice on the env:Envelope start tag.

  - Dennis

Re: [axis2] Writing an empty element?

Posted by Aleksander Slominski <as...@cs.indiana.edu>.
Glen Daniels wrote:

> Hi Alek:
>
>>>> BTW: to bad that solutoion from XmlPull API did nto survive in StAX 
>>>> i.e. it was intelligent to do <empty/> by default unless you called 
>>>> character("") in between.
>>>
>>>
>>> +1, that's what Axis 1 does as well.
>>
>>
>> hmm,  i will take a look and see if i can change this for StAX RI - 
>> after all infoset is equivalent ...
>
>
> +1!  That would rock.

please pull StAX RI from SVN (http://stax.codehaus.org/Home) and build 
jar file (ant).

then if you run test program (below) it should be producing this:

Created not using repairing :-
<?xml version='1.0' encoding='utf-8'?><env:Envelope 
xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
xmlns:test="http://someTestUri"><env:Body><test foo="bar"/><test 
foo="bar"></test><test foo="bar"> </test></env:Body></env:Envelope>
Created  using repairing :-
<?xml version='1.0' encoding='utf-8'?><env:Envelope 
xmlns:env="http://www.w3.org/2003/05/soap-envelope" 
xmlns:test="http://someTestUri" xmlns:test="http://someTestUri" 
xmlns:env="http://www.w3.org/2003/05/soap-envelope"><env:Body><test 
foo="bar"/><test foo="bar"></test><test foo="bar"> 
</test></env:Body></env:Envelope>

thanks.

alek

-----
package samples;

import java.io.StringWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/**
 * Requires StAX RI 1.0 (JSR 173) available at 
http://stax.codehaus.org/Download
 * @author Alek
 */
public class TestSerializeEmptyEl
{
    private final static String SOAP12 =  
"http://www.w3.org/2003/05/soap-envelope";
   
    public static void doXmlOutput(boolean useRepairing) throws 
XMLStreamException {
        StringWriter buffer = new StringWriter();
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        if (useRepairing) {
            
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", 
Boolean.TRUE);
        }
        XMLStreamWriter out = outputFactory.createXMLStreamWriter(buffer);
        out.writeStartDocument();
        out.writeStartElement("env", "Envelope", SOAP12);
        out.writeNamespace("env", SOAP12);
        out.writeNamespace("test", "http://someTestUri");
        out.writeStartElement("env", "Body", SOAP12);
       
        out.writeStartElement("test");
        out.writeAttribute("foo", "bar");
        out.writeEndElement();
       
        out.writeStartElement("test");
        out.writeAttribute("foo", "bar");
        out.writeCharacters("");
        out.writeEndElement();

        out.writeStartElement("test");
        out.writeAttribute("foo", "bar");
        out.writeCharacters(" ");
        out.writeEndElement();
       
        out.writeEndElement();
        out.writeEndElement();
       
        out.writeEndDocument();
        out.close();
        System.out.println("Created "+(useRepairing ? "" : "not")+" 
using repairing :-");
        System.out.println(buffer);
    }
   
    public static void main(String[] s) throws Exception {
        doXmlOutput(false);
        doXmlOutput(true);
    }
}

-- 
The best way to predict the future is to invent it - Alan Kay


Re: [axis2] Writing an empty element?

Posted by Glen Daniels <gl...@thoughtcraft.com>.
Hi Alek:

>>> BTW: to bad that solutoion from XmlPull API did nto survive in StAX 
>>> i.e. it was intelligent to do <empty/> by default unless you called 
>>> character("") in between.
>>
>> +1, that's what Axis 1 does as well.
> 
> hmm,  i will take a look and see if i can change this for StAX RI - 
> after all infoset is equivalent ...

+1!  That would rock.

writeStartElement("test");
writeAttribute("foo", "bar");
writeEndElement();

<test foo="bar"/>

--Glen

Re: [axis2] Writing an empty element?

Posted by Aleksander Slominski <as...@cs.indiana.edu>.
Glen Daniels wrote:

> Hey Alek:
>
>> in short yes!  XMLStreamWriter.writeEmptyElement() should be called 
>> from OM (see example below).
>
>
> Ah, but writeEmptyElement() doesn't let you write attributes, does it? 
> It can write <test/> but not <test foo="bar"/>, as I understand it.

yes

>
>> however i wonder why you care - from XML 1,0 and Infoset point of 
>> view thos2e two are equivalent!
>
>
> Optimization, less bytes on the wire, accurately reflecting the 
> bytestream that came in one end (yes, I know that the infoset is the 
> same, but I still think it's more polite to be able to accurately 
> reproduce what you got) and went out the other.
>
>> BTW: to bad that solutoion from XmlPull API did nto survive in StAX 
>> i.e. it was intelligent to do <empty/> by default unless you called 
>> character("") in between.
>
>
> +1, that's what Axis 1 does as well.

hmm,  i will take a look and see if i can change this for StAX RI - 
after all infoset is equivalent ...

alek

-- 
The best way to predict the future is to invent it - Alan Kay


Re: [axis2] Writing an empty element?

Posted by Glen Daniels <gl...@thoughtcraft.com>.
Hey Alek:

> in short yes!  XMLStreamWriter.writeEmptyElement() should be called from 
> OM (see example below).

Ah, but writeEmptyElement() doesn't let you write attributes, does it? 
It can write <test/> but not <test foo="bar"/>, as I understand it.

> however i wonder why you care - from XML 1,0 and Infoset point of view 
> thos2e two are equivalent!

Optimization, less bytes on the wire, accurately reflecting the 
bytestream that came in one end (yes, I know that the infoset is the 
same, but I still think it's more polite to be able to accurately 
reproduce what you got) and went out the other.

> BTW: to bad that solutoion from XmlPull API did nto survive in StAX i.e. 
> it was intelligent to do <empty/> by default unless you called 
> character("") in between.

+1, that's what Axis 1 does as well.

--Glen

Re: [axis2] Writing an empty element?

Posted by Aleksander Slominski <as...@cs.indiana.edu>.
Glen Daniels wrote:

> Anyone have a clue if there is a way to use the XMLStreamWriter to get:
>
> <elem attr="1"/>
>
> instead of:
>
> <elem attr="1"></elem>

Glen,

in short yes!  XMLStreamWriter.writeEmptyElement() should be called from 
OM (see example below).

>
> for elements with attributes but no content?

however i wonder why you care - from XML 1,0 and Infoset point of view 
thos2e two are equivalent!

>
> If not, this seems VERY BAD.

:)

alek
BTW: to bad that solutoion from XmlPull API did nto survive in StAX i.e. 
it was intelligent to do <empty/> by default unless you called 
character("") in between.

ps. short example:

package samples;

import java.io.StringWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/**
 * Requires StAX RI 1.0 (JSR 173) available at http://stax.codehaus.org/
 * @author Alek
 */
public class TestSerializer3
{
    private final static String SOAP12 =  
"http://www.w3.org/2003/05/soap-envelope";
   
    public static void doXmlOutput(boolean useRepairing) throws 
XMLStreamException {
        StringWriter buffer = new StringWriter();
        XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
        if (useRepairing) {
            
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", 
Boolean.TRUE);
        }
        XMLStreamWriter out = outputFactory.createXMLStreamWriter(buffer);
        out.writeStartDocument();
        out.writeStartElement("env", "Envelope", SOAP12);
        out.writeNamespace("env", SOAP12);
        out.writeNamespace("test", "http://someTestUri");
        out.writeEmptyElement("env", "Body", SOAP12);
        out.writeEndElement();
        out.writeEndDocument();
        out.close();
        System.out.println("Created "+(useRepairing ? "" : "not")+" 
using repairing :-");
        System.out.println(buffer);
    }
   
    public static void main(String[] s) throws Exception {
        doXmlOutput(false);
        doXmlOutput(true);
    }
}


-- 
The best way to predict the future is to invent it - Alan Kay