【问题标题】:Control order of XML attributes in outputed file in JavaJava中输出文件中XML属性的控制顺序
【发布时间】:2011-12-26 14:52:58
【问题描述】:

如何控制 XML 属性在输出文件中的列出顺序?

默认情况下,它们似乎是按字母顺序排列的,而我发送这个 XML 的程序显然没有处理。

例如我希望先显示zzzz,然后在下面的代码中显示bbbbb

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element root = doc.createElement("requests");
doc.appendChild(root);
root.appendChild(request);
root.setAttribute("zzzzzz", "My z value");
root.setAttribute("bbbbbbb", "My b value");

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(file));
transformer.transform(source, result);

【问题讨论】:

标签: java xml


【解决方案1】:

属性的顺序在 XML 中被定义为无关紧要:任何符合标准的 XML 应用程序都不应该产生依赖于属性出现顺序的结果。因此,序列化程序(生成词法 XML 作为输出的代码)通常不会让您控制顺序。

现在,出于美观的原因,拥有该控件有时会很好,因为 XML 被设计为人类可读的。因此,需要该功能是有正当理由的。但事实是,我知道没有提供它的序列化程序。

【讨论】:

  • 是的。但不仅仅是出于美观的原因。我正在生成 2 个 xml 文件,我需要手动比较它们并直观地查看差异。
  • 答案已过时。如今,Saxon 提供 (a) saxon:attribute-order 作为一种控制序列化属性顺序的方法,以及 (b) 根据规范 XML 规范进行序列化的选项,这使您能够以词法形式比较文档。跨度>
  • 顺便说一句,我们发现 Edge 浏览器不保留属性顺序,这导致大量 W3C 测试失败,直到我们修复测试。
  • 我想警告阅读此答案并决定尝试 Saxon 的开发人员:当前免费版本 Saxon-HE:10.3 不允许使用也不 SAXON_ATTRIBUTE_ORDER (尽管在未指定此属性的情况下保持顺序)也不是 SAXON_INDENT_SPACES(默认为 3,这与 Java 代码约定不同,其中 1 个制表符是 4 个空格)。
  • 是的,没错。一般来说,作为 W3C 规范扩展提供的所有 Saxon 语言功能都需要 Saxon-PE 或更高版本,这是一种商业产品。
【解决方案2】:

当我使用 XML DOM API 写入文件时,我遇到了同样的问题。为了解决这个问题,我不得不使用XMLStreamWriter。属性按照您使用XMLStreamWriter 编写的顺序出现在xml 文件中。

【讨论】:

  • 下次如果你能提供至少一个小例子,而不仅仅是陈述会更有用......
【解决方案3】:

XML 规范化导致一致的属性排序,主要是为了允许人们检查部分或全部 XML 的签名,尽管还有其他潜在用途。这可能适合您的目的。

【讨论】:

    【解决方案4】:

    如果您不想将其他框架仅用于自定义属性顺序,您只需将顺序标识符添加到属性即可。

    <someElement a__price="32" b__amount="3"/>
    

    在 XML 序列化器完成后处理原始 XML,如下所示:

    public static String removeAttributeOrderIdentifiers(String xml) {
        return xml.replaceAll(
            " [a-z]__(.+?=\")", 
            "$1"
        );
    }
    

    你会得到:

    <someElement amount="3" price="32"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-11
      • 2017-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 1970-01-01
      • 2014-09-29
      相关资源
      最近更新 更多