2

我读过很多帖子,人们询问有关对 XML 元素强制执行某些属性顺序的问题,一般的回答是它不合法/必需/允许/相关/其他。

我不是在寻找任何回应说我不应该关心属性顺序,所以如果这是你的观点,请不要回复。

我有一个真正的问题需要解决。大型企业产品在其产品的最新版本中将以下两个元素视为不同

<objquestion allowmultiple="true" id="7432" idtext="7433" idvar="7429" parent="7430" questiontype="multchoice">

<objquestion id="7432" idtext="7433" idvar="7429" parent="7430" questiontype="multchoice" allowmultiple="true">

特别是,如果“allowmultiple”属性位于“questiontype”之后,则它充当问题类型的修饰符。如果它是以前的,它会被忽略 - 它不应该是。

因此,他们不太可能在短期内修复他们的产品。

我正在使用这个 XML 内容

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
doc = dbf.newDocumentBuilder().parse(new InputSource(path));

并且内部实现会对 DOM 节点映射中的属性进行排序。当它被写回文件时,它会按照现在的排序顺序写入属性。我有很多使用 XPath 处理 Document 对象的代码。

当我完成对文档的操作后,我目前将其写回

Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(new DOMSource(lc.getDocument()), new StreamResult(new File(paths[1])));

我需要做的是确保在 questiontype 之后写入 allowmultiple 属性。

我试图了解我是否可以影响用于写回 DOM 树的序列化,或者我是否可以简单地替换一个最初不将属性解析为排序映射的不同实现。我想两者都会起作用,但我无法找到如何做到这一点。

我查看了 LSSerializer,但我不确定如何拦截该特定元素。我是否必须扩展 FileOutputStream 并寻找一些东西?

我已经读过 SAX 可能不会进行初始排序,但我需要能够在没有太多新代码的情况下放入解析器,并且对整个 XML 世界并不那么强大。

谁能建议一种方法来做到这一点?

4

3 回答 3

4

下一个 Saxon 版本(9.5,即将到期)有一个序列化属性,允许您控制属性顺序。它是为合法的用例添加的(例如,它可以提高人类的可读性,让 id 属性总是放在第一位),我有点遗憾的是,它最终会被用于像你这样的用例,因为它的无能和不负责任导致大公司雇用的程序员,但就这样吧:如果它解决了问题,我不会哭。

于 2013-04-16T08:19:45.383 回答
0

这听起来像是一个 hack,但你可以用 x1allowmultiple 之类的东西重命名这个属性,然后它将是最后一个:

  • 搜索并用 x1allowmultiple 替换所有出现的 allowmultiple
  • 使用 x1allowmultiple 处理和创建输出文件
  • 搜索并用 allowmultiple 替换所有出现的 x1allowmultiple
于 2013-04-16T07:54:52.647 回答
0

您可以使用JAXB 方法并查看示例以了解元素属性排序。

于 2014-04-08T11:09:42.363 回答