【问题标题】:Java XML Prettyprinting incorporates DTD Comments?Java XML Prettyprinting 包含 DTD 注释?
【发布时间】:2018-07-16 10:45:09
【问题描述】:

使用内置 Java(使用 jdk 8u151 和 8u161 测试)XML 处理引擎解析 XML 数据时,我得到奇怪的结果。如果我在 DTD 中使用参数实体引用,则所有以下来自 DTD 的 SGML 注释都会出现在输出文档中。

这是我正在运行的(最少的)代码:

import java.io.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

public class FormatBug {

    public static void main( String[] args ) throws Exception {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        Reader in = new FileReader( args[0] );
        Writer out = new FileWriter( args[1] );
        t.transform( new SAXSource( new InputSource(in) ), new StreamResult(out) );
        out.flush();
        out.close();
    }
}

源文档如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE doc SYSTEM "doc.dtd">
<doc><p>This is a <b>bold</b> line.</p></doc>

DTD (doc.dtd) 如下所示:

<!ELEMENT doc (p+)>
<!ENTITY % floats "b" >
<!-- comment before -->
<!ELEMENT p ( #PCDATA | %floats; )*>
<!-- comment after -->
<!ELEMENT b (#PCDATA)>

结果如下:

<!-- comment after --><!DOCTYPE doc SYSTEM "doc.dtd">
<doc><p>This is a <b>bold</b> line.</p></doc>

将 p 的规则替换为

<!ELEMENT p ( #PCDATA | b )*>

虚假评论消失。

有人能解释一下这里发生了什么吗?

我还检查了 all cmets 被复制的 JDK 9.0.4,所以我认为我可能做错了什么。

【问题讨论】:

    标签: java xml-parsing dtd xalan


    【解决方案1】:

    我可以确认这发生在 JDK 1.8.0_151 上,并认为这是一个问题,因为使用SAXSource 作为转换的输入源,因为Java's javax.xml.parsers.SAXParser ignores comments

    以下使用 StAX 的变体不会在 JDK 1.8 上打印虚假 cmets,因此可能有助于实现在 JDK 1.8 和 1.9 上运行统一的 Java 源代码:

    import java.io.*;
    import javax.xml.stream.*;
    import javax.xml.transform.*;
    import javax.xml.transform.stax.*;
    import javax.xml.transform.stream.*;
    
    public class FormatBugUsingStaX {
    
        public static void main(String[] args) throws Exception {
    
            InputStream inputStream = new FileInputStream(args[0]);
            InputStreamReader in = new InputStreamReader(inputStream);
            XMLInputFactory factory = XMLInputFactory.newInstance();
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            XMLStreamReader streamReader = factory.createXMLStreamReader(in);
            Writer out = new FileWriter(args[1]);
            t.transform(new StAXSource(streamReader), new StreamResult(out));
        }
    }
    

    编辑:如果您打算保留 cmets,您可能会通过使用另一个 StAX 实现来获得好运;参看。 Transforming a StAX Source in Java

    【讨论】:

      猜你喜欢
      • 2016-01-18
      • 2011-06-12
      • 2012-01-24
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      相关资源
      最近更新 更多