使用dom4j解析xml文件并反向生成为xml文本

旅行者

反向生成仅为测试解析是否正确。

代码:


import org.dom4j.Attribute;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.Element;

import org.dom4j.io.SAXReader;


import java.io.*;

import java.util.List;


public class Test {

public static void main(String[] args) throws DocumentException {

Document document = new SAXReader().read(new File("C:\\Users\\user\\Desktop\\workspace.xml"));

Element root = document.getRootElement();

String attrs = getAttrs(root);

System.out.println("<" + root.getName() + ("".equals(attrs) ? ">" : " " + attrs + ">"));

printElement(root, 1);

System.out.println("</" + root.getName() + ">");

}


private static void printElement(Element root, int marginLevel) {

List<Element> elementList = root.elements();

for (Element element : elementList) {

String attrs = getAttrs(element);

System.out.print(getSpace(marginLevel) + "<" + element.getName() + ("".equals(attrs) ? "" : " " + attrs));

String text = element.getText();

int childLength = element.elements().size();

if (childLength == 0 && text.trim().length() == 0) {

System.out.println("/>");

} else {

System.out.println(">");

if (childLength > 0)

printElement(element, marginLevel + 1);

if (text.trim().length() > 0)

System.out.println(getSpace(marginLevel) + text);

System.out.println(getSpace(marginLevel) + "</" + element.getName() + ">");

}

}

}


private static String getAttrs(Element element) {

List<Attribute> attributes = element.attributes();

if (attributes.size() == 0)

return "";

StringBuilder builder = new StringBuilder(16);

for (Attribute attr : attributes) {

builder.append(attr.getName()).append("=\"").append(attr.getValue()).append("\" ");

}

return builder.substring(0, builder.length() - 1);

}


private static String getSpace(int length) {

StringBuilder builder = new StringBuilder();

for (int i = 0; i < length * 4; i++) {

builder.append(" ");

}

return builder.toString();

}

}


主 楼 发布于:2019-02-01 15:17:43回复
旅行者

经测试,简单的xml文件是没有问题的,有个小缺点是不管某个节点的value和关闭标签是否在同一行,反向生成后的xml中的value都是换行的。

对复杂的xml,如ibatis配置文件,出现value和子节点穿插分布的情况,此时解析和反向生成就出问题了。因为上面获取的value是一次性获取的,相当于把子节点屏蔽掉了直接获取所有value,这跟实际情况是有出入的。不知道ibatis是否做过特殊处理?不管怎么说,通过简单的几十行代码,能做到这个程度我觉得非常不错了。

2 楼 发布于:2019-02-01 15:25:00
回复
旅行者

原始xml:


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

<project version="4">

<component name="ArtifactsWorkspaceSettings">

<artifacts-to-build>

<artifact name="Test:war exploded" />

</artifacts-to-build>

</component>

<component name="ChangeListManager">

<list default="true" id="0210befc-2794-4b27-be2b-e4f2f9998b96" name="Default" comment="" />

<ignored path="$PROJECT_DIR$/out/" />

<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />

<option name="TRACKING_ENABLED" value="true" />

<option name="SHOW_DIALOG" value="false" />

<option name="HIGHLIGHT_CONFLICTS" value="true" />

<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />

<option name="LAST_RESOLUTION" value="IGNORE" />

</component>

<component name="DatabaseView">

<option name="SHOW_INTERMEDIATE" value="true" />

<option name="GROUP_SCHEMA" value="true" />

<option name="GROUP_CONTENTS" value="false" />

<option name="SORT_POSITIONED" value="false" />

<option name="SHOW_TABLE_DETAILS" value="true" />

<option name="SHOW_EMPTY_GROUPS" value="false" />

<option name="AUTO_SCROLL_FROM_SOURCE" value="false" />

<expand />

<select />

</component>

<component name="FavoritesManager">

<favorites_list name="Test" />

</component>

<component name="FileEditorManager">

<leaf SIDE_TABS_SIZE_LIMIT_KEY="375">

<file leaf-file-name="Test.java" pinned="false" current-in-tab="true">

<entry file="file://$PROJECT_DIR$/src/Test.java">

<provider selected="true" editor-type-id="text-editor">

<state relative-caret-position="96">

<caret line="15" column="102" lean-forward="false" selection-start-line="15" selection-start-column="59" selection-end-line="15" selection-end-column="102" />

<folding />

</state>

</provider>

</entry>

</file>

<file leaf-file-name="Element.class" pinned="false" current-in-tab="false">

<entry file="jar://$PROJECT_DIR$/lib/dom4j-1.6.1.jar!/org/dom4j/Element.class">

<provider selected="true" editor-type-id="text-editor">

<state relative-caret-position="151">

<caret line="84" column="9" lean-forward="false" selection-start-line="84" selection-start-column="9" selection-end-line="84" selection-end-column="9" />

<folding />

</state>

</provider>

</entry>

</file>


3 楼 发布于:2019-02-01 15:28:31
回复
旅行者

反向生成的:


<project version="4">

<component name="ArtifactsWorkspaceSettings">

<artifacts-to-build>

<artifact name="Test:war exploded"/>

</artifacts-to-build>

</component>

<component name="ChangeListManager">

<list default="true" id="0210befc-2794-4b27-be2b-e4f2f9998b96" name="Default" comment=""/>

<ignored path="$PROJECT_DIR$/out/"/>

<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true"/>

<option name="TRACKING_ENABLED" value="true"/>

<option name="SHOW_DIALOG" value="false"/>

<option name="HIGHLIGHT_CONFLICTS" value="true"/>

<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false"/>

<option name="LAST_RESOLUTION" value="IGNORE"/>

</component>

<component name="DatabaseView">

<option name="SHOW_INTERMEDIATE" value="true"/>

<option name="GROUP_SCHEMA" value="true"/>

<option name="GROUP_CONTENTS" value="false"/>

<option name="SORT_POSITIONED" value="false"/>

<option name="SHOW_TABLE_DETAILS" value="true"/>

<option name="SHOW_EMPTY_GROUPS" value="false"/>

<option name="AUTO_SCROLL_FROM_SOURCE" value="false"/>

<expand/>

<select/>

</component>

<component name="FavoritesManager">

<favorites_list name="Test"/>

</component>

<component name="FileEditorManager">

<leaf SIDE_TABS_SIZE_LIMIT_KEY="375">

<file leaf-file-name="Test.java" pinned="false" current-in-tab="true">

<entry file="file://$PROJECT_DIR$/src/Test.java">

<provider selected="true" editor-type-id="text-editor">

<state relative-caret-position="96">

<caret line="15" column="102" lean-forward="false" selection-start-line="15" selection-start-column="59" selection-end-line="15" selection-end-column="102"/>

<folding/>

</state>

</provider>

</entry>

</file>

<file leaf-file-name="Element.class" pinned="false" current-in-tab="false">

<entry file="jar://$PROJECT_DIR$/lib/dom4j-1.6.1.jar!/org/dom4j/Element.class">

<provider selected="true" editor-type-id="text-editor">

<state relative-caret-position="151">

<caret line="84" column="9" lean-forward="false" selection-start-line="84" selection-start-column="9" selection-end-line="84" selection-end-column="9"/>

<folding/>

</state>

</provider>

</entry>

</file>

4 楼 发布于:2019-02-01 15:29:46
回复
未知粉肠

亲爱的用户,您的手机号码在我市有奖入网活动中了头奖,奖金为1万元,请您持手枪到任一家银行领取,密码:不许动

5 楼 发布于:2025-01-09 03:31:07
回复

发表回复: