JDOM Transformer - 不收缩空元素

时间:2016-03-05 19:15:21

标签: java xslt jdom

我正在使用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(无论是在转换阶段还是输出中)阶段,但我猜测问题出在输出阶段)。

4 个答案:

答案 0 :(得分:2)

您可以在元素之间使用zero-width-space。这不会影响HTML输出,但会将open-close-tags分开,因为它们具有非空内容。

<div class="someclass">&#8203;<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 TransformerJDOMSourceStreamResult一起使用,然后如果输出,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);
        }
    }

}

我知道,这很脏,但我遇到了同样的问题而没有找到其他方法。