操纵XML元素属性的顺序

时间:2013-04-16 05:37:22

标签: java xml dom

我读了许多帖子,其中人们询问了如何对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])));

我需要做的是确保在问题类型之后写入allowmultiple属性。

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

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

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

有人可以建议这样做吗?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

这听起来像是一个黑客,但你可以用x1allowmultiple重命名这个属性然后它将是最后一个:

  • 使用x1allowmultiple
  • 搜索并替换所有出现的allowmultiple
  • 使用x1allowmultiple
  • 进行处理并创建输出文件
  • 使用allowmultiple
  • 搜索并替换x1allowmultiple的所有出现

答案 2 :(得分:0)

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