我正在使用JDOM 2.0.6将XSLT转换为HTML,但我遇到了以下问题 - 有时候数据应该是空的,也就是说,我将在我的XSLT中有以下内容: / p>
<div class="someclass"><xsl:value-of select="somevalue"/></div>
当somevalue
为空时,我得到的输出是:
<div class="someclass"/>
这可能是完全有效的XML,但是不是有效的HTML,并且在显示结果页面时会导致问题。
<span>
或<script>
标记也存在类似问题。
所以我的问题是 - 如何告诉JDOM不要收缩空元素,并将它们保留为<div></div>
?
修改
我怀疑问题不在实际的XSLTTransformer
中,而是在使用JDOM写入html时。这是我使用的代码:
XMLOutputter htmlout = new XMLOutputter(Format.getPrettyFormat());
htmlout.getFormat().setEncoding("UTF-8");
Document htmlDoc = transformer.transform(model);
htmlDoc.setDocType(new DocType("html"));
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(outHtml), "UTF-8")) {
htmlout.output(htmlDoc, osw);
}
目前提出的添加零宽度空间的解决方案对我有用,但我很想知道是否有办法告诉JDOM将文档视为HTML(无论是在转换阶段还是输出中)阶段,但我猜测问题出在输出阶段)。
答案 0 :(得分:2)
您可以在元素之间使用zero-width-space。这不会影响HTML输出,但会将open-close-tags分开,因为它们具有非空内容。
<div class="someclass">​<xsl:value-of select="somevalue"/></div>
下行是:标签不再是空的。如果您的输出是XML,那将很重要。但对于HTML--这可能是处理的最后阶段 - 它应该不重要。
答案 1 :(得分:1)
在您的情况下,XML转换直接发生在文件/流中,它不再受JDOM的控制。
在JDOM中,您可以选择JDOM文档的输出是否已扩展,或者是否为空元素的未扩展输出。通常,人们从JDOM输出如下:
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
xout.output(document, System.out);
您可以修改输出格式,expand the empty elements
Format expanded = Format.getPrettyFormat().setExpandEmptyElements(true);
XMLOutputter xout = new XMLOutputter(expanded);
xout.output(document, System.out);
如果你'恢复'&#39; (假设它是有效的XHTML?)XSLT将xml转换为新的JDOM文档,您可以使用展开的空元素输出结果。
答案 2 :(得分:0)
如果要转换为HTML文件,请考虑将Jaxp Transformer
与JDOMSource
和StreamResult
一起使用,然后如果输出,Transformer会将转换结果序列化为HTML方法是html
(在代码中设置或使用名为html
的无命名空间根元素完成。
答案 3 :(得分:0)
除了&#34; expandEmptyElements&#34;选项,您可以创建自己的编写器并将其传递给XMLOutputter:
XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setExpandEmptyElements(true));
StringWriter writer = new HTML5Writer();
outputter.output(document, writer);
System.out.println(writer.toString());
然后,本作者可以修改所有HTML5 void元素。像&#34;脚本&#34;等元素例如,没有被触及:
private static class HTML5Writer extends StringWriter {
private static String[] VOIDELEMENTS = new String[] { "area", "base", "br", "col", "command", "embed", "hr",
"img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" };
private boolean inVoidTag;
private StringBuffer voidTagBuffer;
public void write(String str) {
if (voidTagBuffer != null) {
if (str.equals("></")) {
voidTagBuffer.append(" />");
super.write(voidTagBuffer.toString());
voidTagBuffer = null;
} else {
voidTagBuffer.append(str);
}
} else if (inVoidTag) {
if (str.equals(">")) {
inVoidTag = false;
}
} else {
for (int i = 0; i < VOIDELEMENTS.length; i++) {
if (str.equals(VOIDELEMENTS[i])) {
inVoidTag = true;
voidTagBuffer = new StringBuffer(str);
return;
}
}
super.write(str);
}
}
}
我知道,这很脏,但我遇到了同样的问题而没有找到其他方法。