java XMLSerializer避免复杂的空元素

java XMLSerializer避免复杂的空元素,java,xmlserializer,Java,Xmlserializer,我有这个密码: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); DOMImplementation impl = builder.getDOMImplementation(); Document xmldoc = impl.createDocument(null

我有这个密码:

    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());
我可以安慰你:

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

但是,我想得到这个:

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

有人知道如何设置XMLSerializer以避免复杂的空元素吗?
谢谢。

结果:我认为这是不可能的。XMLSerializer不支持此类配置

分析: 当您调用
serializer.serialize(root)
时,将调用该方法。它定义了要序列化的节点类型,并选择了适当的处理方法

当涉及到文本节点时,它调用方法:

\打印机打印文本(“”);
意见:
我不确定是否没有干净的解决方案,我认为这是最后的解决方案。无论如何,您应该查看源代码和/或文档以了解更多信息。

我对XMLSerializer也有同样的问题,XMLSerializer不允许呈现空标记的自定义。我的解决方案是扩展原始XMLSerializer代码并重写serializeElement方法:

我已复制了原始代码并更改了结束打印部分:

受保护的元素(元素elem)抛出IOException

if(isselfclosinglement(elem))
_打印机。打印文本(“/>”);
其他的
_打印机。打印文本(“>”);
其中,isSelfClosingElement包含一个自关闭元素列表


注意:此外,您需要复制printtribute()printNamespaceAttr()方法,因为它被标记为private而不是protected。

我认为您无法更改它。这两个版本是等效的。为什么要避免复杂的空元素?我的应用程序是两个应用程序之间的一种转换器,它将应用程序1生成的文件解析为xml文件,并将其作为应用程序2的输入。但是App2不接受这种输入。难道不可能通过doctype或类似的st来设置吗?从语言定义的角度来看,这两个版本是等效的,因此DTD或XSD中没有构造来防止使用空标记。我的意见是,您应该让app2接受输入(因为它是一个有效的输入,所以应该进行处理),或者如果您无权访问该应用,您可以更改app1返回的xml字符串(stream.toString())。更确切地说,您应该在字符串中查找所有“”模式,并将其替换为“”。我的意见是,为了软件的稳定性,您应该让app2使用空元素接受输入。不接受
的应用程序不能声明读取XML。+1这在标准Xerces序列化程序中是绝对不可能的。这可能与其他序列化程序,但我不知道有任何立即这样做,也不能在谷歌上找到任何东西。
// 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...
}
_printer.printText( "/>" );
_printer.printText( "</" );
_printer.printText( elem.getTagName() );
_printer.printText( ">" );
if (isSelfClosingElement(elem))
    _printer.printText("/>");
else
_printer.printText("></" + elem.getTagName() + ">");