如何让Java.xml.Transformer输出一个没有任何无用空间或换行符的xml?

时间:2015-11-06 09:58:41

标签: java xml jaxp

我的代码:

import org.w3c.dom.Node;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

private String getStringByJAXP(Node input) {
        StreamResult xmlOutput;
        try {
            xmlOutput = new StreamResult(new StringWriter());
            transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            transformer.transform(new DOMSource(input), xmlOutput);
        } catch (TransformerException e) {
            throw new IllegalArgumentException();
        }
        return xmlOutput.getWriter().toString();
    }

输出:

<aaa>
    <a>text a</a>
    <b>
        <c>text c</c>
    </b>
    <f>
        <g><h a="xxx"/></g>
    </f>
</aaa>

但我想输出如下:

<aaa><a>text a</a><b><c>text c</c></b><f><g><h a="xxx" /></g></f></aaa>

请注意,我无法通过一些简单的字符串替换来完成该任务,因为<a>text a</a>中的空格不应被替换(<a>texta</a><a>text a</a>完全不同})。

编辑:

OutputKeys.INDENT, "no"不起作用。更新的代码:

private String getStringByJAXP(Node input) {
    StreamResult xmlOutput;
    try {
        xmlOutput = new StreamResult(new StringWriter());
        transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        transformer.setOutputProperty(OutputKeys.INDENT, "no");
        transformer.transform(new DOMSource(input), xmlOutput);
    } catch (TransformerException e) {
        throw new IllegalArgumentException();
    }
    return xmlOutput.getWriter().toString();
}

2 个答案:

答案 0 :(得分:1)

我有一次类似的案子。 我首先尝试了 transformer.setOutputProperty(OutputKeys.INDENT,“no”); ,但这不起作用。 问题是我的原始节点有额外的“新行”文本节点。

Strip whitespace and newlines from XML in Java的答案为我修好了。基本上,您只需在转换父节点之前删除不必要的文本节点。

我最终使用了这个:

public static void trimWhitespace(Node node)
{
    NodeList children = node.getChildNodes();
    for(int i = 0; i < children.getLength(); ++i) {
        Node child = children.item(i);
        if(child.getNodeType() == Node.TEXT_NODE) {
            child.setTextContent(child.getTextContent().trim());
        }
        trimWhitespace(child);
    }
}

答案 1 :(得分:0)

您可以将XSLT样式表传递给Transformer,其优点是您不必两次分析文档。

InputStream xsltStream = getClass().getResourceAsStream("trim-whitespace.xslt");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xsltStream));

trim-whitespace.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- copy all elements as they are -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*/text()[not(normalize-space())]" />
</xsl:stylesheet>