8

我的 Java 程序如下所示:

public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db;
    try {
        db = dbf.newDocumentBuilder();
        Document document = db.parse(new ByteArrayInputStream("<test><test1></test1></test>".getBytes("UTF-8")));
        StringWriter stringWriter = new StringWriter();
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "no");
        transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");
        transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
        System.out.println(stringWriter.toString());
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (TransformerConfigurationException e) {
        e.printStackTrace();
    } catch (TransformerException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    }
}

输出是:<test><test1/></test>我想要输出<test><test1></test1></test>

因为我使用JasperReportshtml样式只允许我想要的输出。如何做到这一点?是否有 Transformer 的任何输出属性或DocumentBuilderFactory的任何属性来做想要的输出?

4

2 回答 2

8

如果在调用 transformer.transform 之前添加此行 - 输出将采用 html 样式:

transformer.setOutputProperty(OutputKeys.METHOD, "html");
于 2014-01-13T09:42:01.570 回答
3

使 Java 的 Transformer 编写完整的结束标记的一种方法是对 Document 进行少量更改。就我而言,我自己构建 DOM(而不是从字符串解析 XML)。对于我知道它将创建一个自闭合标签的每个节点,我必须(不幸地)添加一个带有一些随机内容的 textNode,您知道它肯定不会出现在内容本身中。这就是我为不添加任何其他子元素的元素所做的(因此将成为自闭合标签):

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element test = doc.createElement("test");
doc.appendChild(root);
Element element = doc.createElement("test1");
element.appendChild("_plchldr_"); // because we know it doesn't have children

如果是现有 Document,则必须遍历它才能找到没有子元素的元素。将这些相同的占位符添加到它们。

稍后,当将此 XML 流式传输到我们的 Writer 时,必须从生成的 XML 中删除这些占位符:

TransformerFactory factory = TransformerFactory.newInstance();
transformer.setOutputProperty("omit-xml-declaration", "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
// and here's the trick:
System.out.println( sw.toString().replaceAll("_plchldr_", "") );

或者,您可以使用删除“_plchldr_”流的包装 Writer。考虑到我的 XML 的大小(<4KB),我没有费心去写一个。

另一种选择,如果您不想替换输出中的文本,您可以添加注释而不是文本节点:

element.appendChild(doc.createComment(" "));

结果不需要删除这些占位符即可成为有效的 XML,但是,您的输出中将包含毫无意义的注释。

我认为这是一个肮脏的解决方法,但它至少有效!

于 2016-07-07T16:02:02.223 回答