Java 预打印。忽略空白
温柔点 我正在尝试使用javax.xml.transform.Transformer格式化一些xml字符串,以便在标记之间缩进/无空格。如果标记之间没有空格,则可以正常工作。如果有的话,它会表现得很怪异。我将发布一个示例。我试图跟进以下主题:。没有成功 代码如下:Java 预打印。忽略空白,java,xml,dom,removing-whitespace,Java,Xml,Dom,Removing Whitespace,温柔点 我正在尝试使用javax.xml.transform.Transformer格式化一些xml字符串,以便在标记之间缩进/无空格。如果标记之间没有空格,则可以正常工作。如果有的话,它会表现得很怪异。我将发布一个示例。我试图跟进以下主题:。没有成功 代码如下: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation domImpl = builder.getDOMImplementation();
DOMImplementationLS ls = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
LSInput in = ls.createLSInput();
in.setByteStream(new ByteArrayInputStream(input.getBytes()));
LSParser parser = ls.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS,
"http://www.w3.org/2001/XMLSchema");
Document xmlInput = parser.parse(in);
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
TransformerFactory f = TransformerFactory.newInstance();
f.setAttribute("indent-number", 2);
Transformer transformer = f.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(new DOMSource(xmlInput), xmlOutput);
如果标签之间没有中断
input : <tag><nested> hello </nested></tag>
output :
<tag>
<nested> hello </nested>
</tag>
input:hello
输出:
你好
如果有:
input : <tag> <nested> hello </nested></tag>
output :
<tag> <nested> hello </nested>
</tag>
input:hello
输出:
你好
JVM1.6
这里有什么明显的问题吗 这一定是transformer实现的问题。我创建了一个小测试类,它将不带空格或换行符的字符串作为XML读取,并从XSLT样式表(也从字符串)创建一个转换器。样式表指定必须进行缩进。这基本上是实现transformer.setOutputProperty(OutputKeys.INDENT,“yes”)的另一种方法代码> 这是:
package transformation;
import java.io.StringReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class TransformerTest {
public static void main(String[] args) throws Exception {
final String xmlSample = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><tag><nested>hello</nested></tag>";
final String stylesheet = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method=\"xml\" version=\"1.0\" indent=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>";
final TransformerFactory factory = TransformerFactory.newInstance();
final Source xslSource = new StreamSource(new StringReader(stylesheet));
final Transformer transformer = factory.newTransformer(xslSource);
final Source source = new StreamSource(new StringReader(xmlSample));
final Result result = new StreamResult(System.out);
transformer.transform(source, result);
}
}
包转换;
导入java.io.StringReader;
导入javax.xml.transform.Result;
导入javax.xml.transform.Source;
导入javax.xml.transform.Transformer;
导入javax.xml.transform.TransformerFactory;
导入javax.xml.transform.stream.StreamResult;
导入javax.xml.transform.stream.StreamSource;
公共类转换测试{
公共静态void main(字符串[]args)引发异常{
最后一个字符串xmlSample=“hello”;
最终字符串样式表=”;
最终TransformerFactory=TransformerFactory.newInstance();
最终源xslSource=newstreamsource(newstringreader(样式表));
最终变压器=工厂新变压器(xslSource);
最终源代码=新的StreamSource(新的StringReader(xmlSample));
最终结果=新的StreamResult(System.out);
变换(源、结果);
}
}
奇怪的是,结果因我使用的变压器而异。如果我没有在类路径上放置任何TransformerFactory实现(使用JRE libs中的默认实现),结果是:
<?xml version="1.0" encoding="UTF-8"?>
<tag>
<nested>hello</nested>
</tag>
你好
不正确,因为标记没有缩进
然后,通过在类路径上添加最近的Xalan实现(Xalan.jar和serializer.jar,仍然使用JRE默认解析器/DOM构建器),我得到了以下结果:
<?xml version="1.0" encoding="UTF-8"?><tag>
<nested>hello</nested>
</tag>
你好
仍然不正确,第一个标记与XML声明在同一行,并且没有缩进
说实话,这让我很震惊。我能理解标记之间或文本节点周围的空白是否会影响缩进,因为转换器可能会假定其中一些是不可忽略的。但是看到这样一个简单的XML被破坏是很奇怪的。我认为使用控制台输出可能与此有关,所以我尝试将数据流传输到一个文件。同样的结果
奇怪的是,长期存在的transformer实现仍然存在这种行为。但并没有我注意到使用模式验证程序导致属性从“增强”XML输出中删除时那么糟糕
因此,除了尝试寻找其他处理器,看看它们是否有相同的问题外,似乎没有什么可以做的。也许撒克逊值得一试。这个bug报告也很有趣(不过是针对Java1.5的):
变压器似乎不喜欢空白,因此最简单的解决方案似乎是 删除它
public String prettyPrintXML(String inXML) {
String outXML = inXML;
// The transformer doesn't like white space between tags so remove it.
String[] bits = inXML.split(">");
inXML="";
boolean first = true;
for (int n=0;n<bits.length; n++){
if (first)
inXML = inXML + bits[n].trim();
else
inXML = inXML + ">"+bits[n].trim();
first = false;
}
inXML = inXML + ">";
公共字符串prettyPrintXML(字符串inXML){
字符串outXML=inXML;
//变压器不喜欢标签之间的空白,所以请删除它。
字符串[]位=inXML.split(“>”;
inXML=“”;
布尔值优先=真;
对于(int n=0;n该属性修复了我的问题!谢谢!+1否。也尝试了。变压器只是坏了。