java - 对元素的 DOM 属性序列进行排序

标签 java xml parsing dom w3c

<分区>

这个问题之前在 stackoverflow 中被问过:

setting order of attributes

真的不可能吗?

使用 insertBefore我想对元素的属性序列进行排序。具体来说,在下面的示例中,如何更改属性的顺序?只使用 setAttribute 会更容易吗?从一个节点?在任何一种情况下,顺序似乎都是自动发生的,尽管 insertBefore 肯定意味着可以指定顺序。

代码:

package xml;

import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Main {

    private static final Logger logger = Logger.getLogger(Main.class.getName());

    /**
     * catches errors
     */
    public Main() {
        try {
            createDoc();
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TransformerException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    private void createDoc()
            throws ParserConfigurationException, TransformerConfigurationException, TransformerException, IOException {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setIgnoringComments(false);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
        doc.setXmlStandalone(true);

        Comment comment = doc.createComment(" nodes ");
        doc.appendChild(comment);

        Element root = doc.createElement("foo");
        root.setAttribute("Version", "1.0");
        doc.appendChild(root);

        Element bar = doc.createElement("bar");

        Element baz = doc.createElement("baz");

        Element child1 = doc.createElementNS("foo", "bar");
        child1.setPrefix("prefix1");
        Attr attr1 = doc.createAttribute("attr1");
        attr1.setValue("val1");

        Element child2 = doc.createElementNS("foo", "bar");
        child2.setPrefix("prefix2");
        Attr attr2 = doc.createAttribute("attr2");
        attr2.setValue("val2");

        baz.setAttributeNode(attr2);
        baz.setAttributeNode(attr1);

        root.appendChild(bar);
        bar.appendChild(baz);
        writeToFile(doc);
    }

    private void writeToFile(Document doc)
            throws TransformerConfigurationException, TransformerException, IOException {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        transformerFactory.setAttribute("indent-number", new Integer(2));
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.VERSION, "1.0");
        StringWriter sw = new StringWriter();
        StreamResult result = new StreamResult(sw);
        DOMSource source = new DOMSource(doc);
        transformer.transform(source, result);
        logger.log(Level.INFO, "\n{0}", sw.toString());
        result = new StreamResult(new FileWriter("test.xml"));
        transformer.transform(source, result);
    }

    public static void main(String args[]) {
        Main main = new Main();
    }
}

最佳答案

XML 元素属性的排序不是 XML information set 的一部分,因此实现(包括 DOM、解析器和反解析器)没有义务保留它。

在实践中,这意味着您是否可以通过 DOM API 控制属性的顺序(例如使用 insertBefore)是特定于实现的,并且是否将跨转换保留顺序也是特定于实现的。

我的建议是更改您的应用程序,使其不依赖于 XML 属性排序。

关于java - 对元素的 DOM 属性序列进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4181715/

相关文章:

java - Failsafe RetryPolicy - 从 SupplyAsync 抛出异常

java - 如何在航类从 xml 创建类和对象?

android - XML中没有更多建议

python - 我可以让 Beautiful Soup 保持属性排序和行缩进吗

java - 在 Spring ,有没有办法按名称找到路线?

带有两个 BouncyCaSTLe jar 的 java.lang.NoClassDefFoundError

scala - Scalding:解析带头的逗号分隔数据

php - PHP解析/语法错误;以及如何解决它们

Java 二维数组 for 循环

java - 如何将 XML 元素替换为另一个(另一个文档的)元素?