如何让 Java.xml.Transformer 输出一个 xml 而没有任何无用的 space 或换行符?
How to let Java.xml.Transformer output a xml without any useless space or line break?
我现在的代码:
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>
中的 space(<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();
}
我曾经遇到过类似的情况。
我首先尝试了 transformer.setOutputProperty(OutputKeys.INDENT,"no");,但这没有用。
问题是我的原始节点有额外的 "new line" 个文本节点。
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);
}
}
您可以将 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>
我现在的代码:
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>
中的 space(<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();
}
我曾经遇到过类似的情况。 我首先尝试了 transformer.setOutputProperty(OutputKeys.INDENT,"no");,但这没有用。 问题是我的原始节点有额外的 "new line" 个文本节点。
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);
}
}
您可以将 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>