【问题标题】:DOM avoid preserve whitespacesDOM 避免保留空格
【发布时间】:2016-11-10 09:43:02
【问题描述】:

有什么方法可以避免在 DOM(哪个 java 库)中保留空格?

我有一个通过 XSD 架构验证的 XML 文件。通过这种模式,只有 <text> 元素包含文本。另一个元素仅包含元素节点。当我编辑 XML 文件时,为了获得大多数可见性,我有几种类型的空格,如制表符、空白、回车……

如何在不保留所有未经架构授权的空格的情况下解析我的 XML(没有 xslt,只有 java 库)?

【问题讨论】:

    标签: java xml xsd xml-parsing java-8


    【解决方案1】:

    https://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setIgnoringElementContentWhitespace(boolean) 建议有一个设置“要求解析器处于验证模式”(https://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilderFactory.html#setSchema(javax.xml.validation.Schema)),然后支持忽略仅元素内容模型中的空白。

    这里是一个例子,给定的Java代码

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setIgnoringElementContentWhitespace(true);
    
        Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(new File("schema1.xsd"));
        //dbf.setSchema(schema);
    
        DocumentBuilder db = dbf.newDocumentBuilder();
    
        Document doc = db.parse("file1.xml");
    
        System.out.println(doc.getDocumentElement().getChildNodes().getLength());
    

    带有示例文件

    <root>
        <item>a</item>
        <item>b</item>
    </root>
    

    子节点输出的数量是 5,现在当我从中删除评论时

    dbf.setSchema(schema);
    

    并有一个架构定义元素,仅用于 root 元素的内容,例如

    <xs:schema version="1.0"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               elementFormDefault="qualified">
    
        <xs:element name="root">
            <xs:complexType>
                <xs:sequence maxOccurs="unbounded">
                    <xs:element name="item" type="xs:string"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    
    </xs:schema>
    

    子节点的输出只有 2 个。

    【讨论】:

    • 嗨,马丁,感谢您的回复。我测试了这段代码,在所有情况下我都有 5 个子节点
    • 我使用 Netbeans 8.1 和 Java 1.8 来运行和测试代码,它给出了我在回答中所述的结果。我不确定为什么你会得到不同的结果,也许其他人更了解 API 以及不同 Java 版本对它的支持程度。您可能想要编辑您的问题并说明您正在使用哪个 Java 版本,或者在获得不同结果时需要分别使用哪个 Java 版本。
    • 我也使用 Java 8。
    • 听起来,我在 Windows 上,当我添加 System.out.println("Java version: " + System.getProperty("java.version")); 时,它会输出 Java version: 1.8.0_77
    • 我的合资企业是:Java version: 1.8.0_66。我会尝试 0_77