java XMLSerializer avoid Complex Empty Elements

南笙酒味 提交于 2019-12-23 17:37:22

问题


I've got this code:

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    DOMImplementation impl = builder.getDOMImplementation();
    Document xmldoc = impl.createDocument(null, null, null);

    Element root = xmldoc.createElement("root");
    Element textElement = xmldoc.createElement("text");
    Text textNode = xmldoc.createTextNode("");
    root.appendChild(textElement);
    textElement.appendChild(textNode);

    OutputFormat of = new OutputFormat("XML","UTF-8",true);
    of.setIndent(1);
    of.setIndenting(true);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();

    XMLSerializer serializer = new XMLSerializer(stream, of);
    // As a DOM Serializer
    serializer.asDOMSerializer();
    serializer.serialize(root);

    System.out.println(stream.toString());

I get to console this:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <text/>
</root>

But, I'd like to get this:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <text></text>
</root>

Does anybody know, how to set the XMLSerializer to avoid Complex Empty Elements? Thanks.


回答1:


I had the same problem with XMLSerializer not allowing rendering customization of empty tags. My solution was to extend the original XMLSerializer code and override the serializeElement method:

I have copied the original code and changed the closing printing part:

protected void serializeElement(Element elem) throws IOException ...

if (isSelfClosingElement(elem))
    _printer.printText("/>");
else
_printer.printText("></" + elem.getTagName() + ">");

where isSelfClosingElement holds a list of self closing elements

NOTE: additionally you need to copy the printAttribute() and printNamespaceAttr() method as it is marked private instead of protected.




回答2:


Outcome: I don't think it is possible. XMLSerializer does not support such configuration.

Analysis: When you call serializer.serialize(root), BaseMarkupSerializer's serialize(Element) method is invoked. It defines type of node you pass to serialize and chooses appropriate way to deal with it.

When it comes to the text node, it calls XMLSerializer's serializeElement(Element) method:

// If element has children, then serialize them, otherwise
// serialize en empty tag.       
if (elem.hasChildNodes()) {
    //... irrelevant code...
    endElementIO( null, null, tagName );
} else {
    //... irrelevant code...
    _printer.printText( "/>" ); // <------ HARDCODED, NON-CONFIGURABLE
    //... irrelevant code...
}

Problem: As you can see, way of closing empty element is hardcoded and not configurable (if you look for complete code snippet from source code).

Solution: Since XMLSerializer is not final, you could create your own serializer by extending it and overriding it's method. One of the ways would be changing:

_printer.printText( "/>" );

to

_printer.printText( "</" );
_printer.printText( elem.getTagName() );
_printer.printText( ">" );

Opinion: I am not sure if there is no clean solution and I see this solution as the last resort solution. Anyway, you should look yourself through the sources and/or documentation for more information.



来源:https://stackoverflow.com/questions/10726974/java-xmlserializer-avoid-complex-empty-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!