在java中解析和修改后如何保留XML中的属性顺序?

如何解决在java中解析和修改后如何保留XML中的属性顺序?

首先,一些前提。

我知道网站上存在几个相同的问题,但在这些问题中我都没有找到问题的明确解决方案。 我知道 xml 文件的属性顺序与数据一致性或与实际将 xml 视为此类而不是字符串的软件集成的能力完全无关。但是,我必须保留它,因为我要修改文件,这些文件将由操作员使用 WinMerge 或 Tortoise 的检查修改命令进行目视检查。 我使用过像 DOM、STAX 和 JDOM 这样的库,但结果很差。 在我只需要修改元素文本的文件中,我没有问题,如果有一些不同的格式,我可以轻松地将其视为字符串进行修改。

有了属性就更复杂了。这些按其他顺序排序(请不要质疑这是否正确不是问题所固有的)并且在 winmerge 上看起来是否所有文档都已修改。

the code is unreadable on purpose

这是我的 xml 首先和修改后的(剪切和半随机文本内容)示例

    <?xml version="1.0" encoding="UTF-8"?>
    <sca:composite xmi:version="2.0" 
      xmlns:xmi="http://www.omg.org/XMI" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:BW="http://xsd.tns.tibco.com/amf/models/sca/implementationtype/BW" xmlns:XMLSchema="http://www.w3.org/2001/XMLSchema" 
      xmlns:compositeext="http://schemas.tibco.com/amx/3.0/compositeext" 
      xmlns:productAvailabilityResp="http://www.example.org/ERTETERET" 
      xmlns:property="http://ns.tibco.com/bw/property" 
      xmlns:rest="http://xsd.tns.tibco.com/bERTERTETE" 
      xmlns:sca="http://www.3453434FDSSDFSD.org/xmlns/sca/1.0" 
      xmlns:scact="http://xsd.tns.tibco.com/23E23E2E23Ee" 
      xmlns:scaext="http://2D2333DD32s" 
      xmi:id="_uKDz4IaiEeipW88nT3HxEA" 
      targetNamespace="http://tns.tibco.com/D23D32DD2232D2D2" 
      name="Q1231W1y" compositeext:version="1.0.0" 
      compositeext:description="TO EDIT VALUE" 
      ompositeext:formatVersion="2">
    </sca:composite>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<sca:composite xmlns:sca="http://www.SDFSDF.org/xmlns/sca/1.0" 
    xmlns:BW="http://xsd.tns.tibco.com/amf/models/sca/SDFS/BW" 
    xmlns:XMLSchema="http://www.w3.org/2001/XMLSchema" 
    xmlns:compositeext="http://schemas.tibco.com/amx/3.0/compositeext" 
    xmlns:productAvailabilityResp="http://www.example.org/SDFSDFSD"
     xmlns:property="http://ns.tibco.com/bw/property" 
     xmlns:rest="http://xsd.tns.tibco.com/SDFSF" 
     xmlns:scact="http://xsd.tns.tibco.com/amf/models/sca/SDFSD" 
     xmlns:scaext="http://xsd.tns.tibco.com/amf/models/sca/extensions" 
     xmlns:xmi="http://www.omg.org/XMI" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     compositeext:description="test EDITED VALUE" 
     compositeext:formatVersion="2" 
     compositeext:version="1.0.0" 
     name="ERFERFRFE" 
     targetNamespace="http://tns.tibco.com/bw/composite/ERFERFREy"
     xmi:id="_uKDz4IaiEeipW88nT3HxEA" 
     xmi:version="2.0">
</sca:composite>

我们可以一起尝试寻找解决方案吗?

按照 Federico 的建议进行编辑:

我需要做的是更改单个属性的值和元素的文本内容,我可以做这两件事。但是当我写回文件时,我发现属性的顺序和格式不同:

<?xml version="1.0" encoding="UTF-8"?>
<sca:composite //same attributes
  compositeext:description="TO EDIT VALUE" 
  //same other attributes>

other stuff 

</sca:composite>

ps:我的目的是为设计师之外的 tibco BW6 项目制作一个版本控制程序

解决方法

据我所知,您的程序从带有 STaX、DOM 或 SAX 的文件中读取 XML 输入流,然后您对元素或属性进行一些修改,最后您的程序会将数据写入另一个 XML 文件。

要求输出文件的详细结构在进行更改后尽可能接近输入文件的结构。这意味着——除其他条件外——元素和属性在输出文档中的顺序必须与它们在输入文档中的顺序相同。

XML 要求元素的顺序保持原样,但是(正如您已经说过的),属性可以按任何顺序排列,而不会对 XML 文档的语义产生任何影响。

您的问题是,DOM、SAX 和 STaX 都不允许您影响元素的属性顺序。

此描述是否与您的问题相符?


我使用一个大型 XML 文件作为“穷人的数据库”;这意味着我使用文本编辑器操作该 XML 文件,并且我有一堆小程序可以从该 XML 文件创建报告。其中之一将对 XML 文件中的“记录”进行排序,这需要读取它、操作数据并在之后写入。

我和你有同样的(至少是类似的问题):之后有些属性位于任意位置。在编辑器中搜索文本文件时,这会造成很大的摩擦。

因此,我没有使用 SAX、DOM 或 STaX 作为输出,而是编写了自己的库,为每个元素类型定义了一个比较器,用于对该元素类型的属性进行排序。

比较器的一些实现使用了一个包含定义顺序的属性名称的列表,这允许我对属性进行如下排序:

<element sortkey="…" id="…" subject="…" date="…" parent="…" …

如果您将 xmi:… 事物和命名空间定义都视为属性,则此类“XMLWriter”的代码非常简单。

如果每个元素的属性顺序可能不同(即使是相同名称的元素),您必须修改该方法,以便在读取时存储每个元素实例的属性序列。

>

但也许 XML 处理根本不适合您……

也许使用 sedawk 之类的方法更适合您的需求。

这基本上意味着您在文本文件中搜索某个序列(使用正则表达式或按行和列号或两者的组合),替换您在那里找到的内容并重新开始在另一个位置进行下一个更改.


编辑:我并不是想将 sedawk 集成到解决方案中;我的意思是只采用这些工具如何工作的基本方法,并在程序中实现它。这两种工具都非常强大,但据我所知,只需要它们的一小部分功能,因此将其中一个完全集成到程序中可能会有些过分——尽管如此,这是可能的: 集成的起点awkawk.sourceforge.net。它甚至可以通过 JSR-223(脚本)进行集成。 对于 sed 的集成,查看 github 上的 tools4j/unix4j project 可能会有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res