用SAX实现修改xml文件内容

背景

在久#工作,N#P#资产管理系统,jmx文件(公司自定义)对应Hibernate的实体类,jmx文件实际上就是一个xml文件。每次新建一个实体类(对NP资产系统而言,就是新建一个jmx文件),都需要一一替换文件中的以下两个元素的uuid:

<id>4371b121-aa9d-4942-8d01-4119b1dbad58</id>
<model:id>6b89a8d9-51d2-4499-a7a1-bf56ff7f9a66</model:id>

一直采用的方法是用网页uuid工具,生成uuid值,然后复制粘贴到文件中,这种最原始的方法,
在文件只包含少数个uuid的情况下还行得通,如果包含十几、几十甚至更多个值,一一复制粘贴,累到眼疼,简直是个噩梦。由此产生新需求。

需求

手写工具,实现uuid自动替换。

思路

用sax复制原jmx文件(也就是xml文件),在复制的过程中,实现uuid重写。

实现

eclipse新建maven工程,选择maven-archetype-quickstart框架。

maven工程结构

在这里插入图片描述

源码

源码复制粘贴到本地,可直接使用。
源文件1:

package com.wj.util.JmxUuidRewriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class JmxUuidRewriter extends DefaultHandler {

    private boolean flag = false;
    private TransformerHandler writeHandler;
    private String destination;
    
    public JmxUuidRewriter(String destination) {
    	this.destination = destination;
    }

    @Override
    public void startDocument() throws SAXException {
        System.out.println("regenerated uuid: ");

        // prepare
        SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        try {
            this.writeHandler = transformerFactory.newTransformerHandler();
            Transformer transformer = writeHandler.getTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            File file = new File(this.destination);
            if(!file.exists()){
                file.createNewFile();
            }
            StreamResult streamResult = new StreamResult(new FileOutputStream(file));
            this.writeHandler.setResult(streamResult);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
			e.printStackTrace();
		}

        // begin
        this.writeHandler.startDocument();
    }

    @Override
    public void endDocument() throws SAXException {
        // end
        this.writeHandler.endDocument();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if(qName.equals("id") || qName.equals("model:id")){
            this.flag = true;
        }

        this.writeHandler.startElement(uri, localName, qName, attributes);
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        this.flag = false;

        this.writeHandler.endElement(uri, localName, qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        char[] ch2 = null;
        if(this.flag){
            String all = new String(ch, 0, ch.length);

            UUID uuid = UUID.randomUUID();
            String content_new = uuid.toString();
            System.out.println(content_new);

            StringBuffer sb = new StringBuffer();
            sb.append(all.substring(0, start).concat(content_new));
            ch2 = sb.toString().toCharArray();
        }
        if(ch2 != null){
            this.writeHandler.characters(ch2, start, length);
        }else{
            this.writeHandler.characters(ch, start, length);
        }
    }
}

源文件2:

package com.wj.util.JmxUuidRewriter;

import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;

public class JmxUuidRewriterMain {

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        SAXParser saxParser = saxParserFactory.newSAXParser();

        JmxUuidRewriter saxTestHandler = new JmxUuidRewriter(args[1]);
        saxParser.parse(new File(args[0]), saxTestHandler);
    }

}

使用

为了便于项目其他人员使用,特将工程打包为java工具,可通过jar命令行直接执行。
导出jar包过程
1、选择工程,邮件,export,搜索jar file
在这里插入图片描述
2、一路next,最后选择可执行main文件,点击finish,即可导出。
在这里插入图片描述
3、在jar包同目录下,打开cmd命令窗口,执行如下命令
java -jar JmxUuidRewriter.jar src.xml destination.xml
src.xml表示源文件名称
destination.xml表示目标文件名称,即复制出来的xml文件名称
或者,将命令行制作为bat脚本,附上脚本全内容:

@echo on
setlocal
title "jmx rewriter"

java -jar JmxUuidRewriter.jar house_xiaoqu.jmx house_xiaoqu2.jmx

echo & pause

4、执行结果截图
在这里插入图片描述

难点解析

在这里插入图片描述

附录

house_xiaoqu.jmx文件内容

<?xml version="1.0" encoding="UTF-8"?>

<metadata xmlns="http://www.beecode.cn/schema/amino-metadata"
	xmlns:model="http://www.beecode.cn/schema/bcp-type"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:dev="http://www.beecode.cn/schema/develop"
	xsi:schemaLocation="http://www.beecode.cn/schema/amino-metadata 
 http://www.beecode.cn/schema/amino-metadata/amino-metadata-1.0.xsd 
http://www.beecode.cn/schema/bcp-type 
http://www.beecode.cn/schema/bcp-type/bcp-type-1.0.xsd">
	<specification>JMX_1.1</specification>
	<id>4371b121-aa9d-4942-8d01-4119b1dbad58</id>
	<name>com.jiuqi.np.gams2.business.bill.house_xiaoqu</name>
	<title>校区单据主表</title>
	<define>bcp.type.Class</define>
	<define-version>1.0.0</define-version>
	<dependency>javax.persistence.Column</dependency>
	<dependency>javax.persistence.Entity</dependency>
	<dependency>javax.persistence.Id</dependency>
	<dependency>javax.persistence.Table</dependency>
	<dependency>com.jiuqi.np.gams2.bill.base.BillMasterBase</dependency>
	<content>
		<model:class>
			<model:annotations>
				<model:annotation>
					<model:type>javax.persistence.Entity</model:type>
				</model:annotation>
				<model:annotation>
					<model:type>javax.persistence.Table</model:type>
					<model:properties>
						<model:property>
							<model:key>name</model:key>
							<model:value>house_xiaoqu</model:value>
						</model:property>
					</model:properties>
				</model:annotation>
			</model:annotations>
			<model:parents>
				<model:parent>com.jiuqi.np.gams2.bill.base.BillMasterBase
				</model:parent>
			</model:parents>
			<model:attributes>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>6b89a8d9-51d2-4499-a7a1-bf56ff7f9a66</model:id>
					<model:name>parentId</model:name>
					<model:title>上级Id</model:title>
					<model:type>uuid</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>4ffab7ff-4a0b-4dde-b79b-94a9389edb32</model:id>
					<model:name>title</model:name>
					<model:title>校区名称</model:title>
					<model:type>string</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>54183315-50e7-4aca-b2da-582a6e462522</model:id>
					<model:name>location</model:name>
					<model:title>坐落位置</model:title>
					<model:type>string</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>a8e49065-4d12-4bb0-9d2a-d95eb253a4f9</model:id>
					<model:name>total_area</model:name>
					<model:title>总面积</model:title>
					<model:type>float</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>d4f8dd36-f6f8-4169-b968-690fdef42974</model:id>
					<model:name>who_builds</model:name>
					<model:title>承建单位</model:title>
					<model:type>string</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>85a16bc1-c41c-42e1-812a-4afb7494e22f</model:id>
					<model:name>start_date</model:name>
					<model:title>开工日期</model:title>
					<model:type>datetime</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>a390acbd-eb38-4f25-ba08-495582fb288d</model:id>
					<model:name>end_date</model:name>
					<model:title>竣工日期</model:title>
					<model:type>datetime</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>3dc15528-24da-413d-9eeb-8718a937edb1</model:id>
					<model:name>value</model:name>
					<model:title>价值</model:title>
					<model:type>float</model:type>
					<model:description />
					<model:default />
				</model:attribute>
				<model:attribute>
					<model:annotations>
						<model:annotation>
							<model:type>javax.persistence.Column</model:type>
						</model:annotation>
					</model:annotations>
					<model:id>a61b0dd5-b5c8-4d91-9daf-fcb117c2be8b</model:id>
					<model:name>description</model:name>
					<model:title>校区简介</model:title>
					<model:type>string</model:type>
					<model:description />
					<model:default />
				</model:attribute>
			</model:attributes>
		</model:class>
	</content>
</metadata>

疑义相与析

如果有疑问,可添加微信联系
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值