package com.ruoyi;
import java.io.File;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.builder.Input;
import org.xmlunit.diff.Comparison;
import org.xmlunit.diff.ComparisonListener;
import org.xmlunit.diff.ComparisonResult;
import org.xmlunit.diff.ComparisonType;
import org.xmlunit.diff.Diff;
import org.xmlunit.diff.Difference;
public class XmlContent {
// 加载XML文档的方法
static Document loadXmlDocument(String filePath) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new File(filePath));
}
// 根据路径获取节点的方法
private static Node getNodeByPath(Document document, String xpath) {
try {
NodeList nodeList = (NodeList) XPathFactory.newInstance().newXPath()
.evaluate(xpath, document, XPathConstants.NODESET);
return nodeList.getLength() > 0 ? nodeList.item(0) : null;
} catch (XPathExpressionException e) {
e.printStackTrace();
return null;
}
}
// 保存XML文档的方法
private static void saveXmlDocument(Document document, String filePath) throws Exception {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 设置缩进和换行符,使输出的XML更易于阅读
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(filePath));
transformer.transform(source, result);
}
public static void main(String[] args) throws Exception {
// 读取两个XML文件的内容
String control = new String(Files.readAllBytes(Paths.get("C:\\abc\\dm-1-2.xml")));
String test = new String(Files.readAllBytes(Paths.get("C:\\abc\\dm-2-3.xml")));
//第一种方式
Diff diff = DiffBuilder.compare(Input.fromString(control))
.withTest(Input.fromString(test))
//.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)) // 使用按名称和文本匹配节点的策略
.checkForSimilar()
.normalizeWhitespace() // 忽略空白字符的差异
//.withComparisonController(ComparisonControllers.StopWhenDifferent) // 当找到第一个差异时停止比较
.withComparisonListeners(new ComparisonListener() {// 自定义差异监听器
@Override
public void comparisonPerformed(Comparison comparison, ComparisonResult outcome) {
// 判断比较结果
// if (outcome == ComparisonResult.DIFFERENT) {
// // 获取差异所在的节点
// Node controlNode = comparison.getControlDetails().getTarget();
// Node testNode = comparison.getTestDetails().getTarget();
// String controlTextContent = controlNode.getTextContent(); // 获取控制节点的文本内容
// String testTextContent = testNode.getTextContent(); // 获取测试节点的文本内容
// // 对差异内容进行标记(这里我们简单地添加一个名为'different'的CSS类)
// String formattedControlValue = "<b font='color:red;'>" + controlTextContent + "</b>";
// String formattedTestValue = "<b font='color:red;'>" + testTextContent + "</b>";
// testNode.setTextContent(formattedTestValue);
// controlNode.setTextContent(formattedControlValue);
// }
}
})
.build();
//第二种方式适用Document更新下节点Node对应
// 加载XML文档1
Document document1 = loadXmlDocument("C:\\abc\\dm-1-2.xml");
//加载XML文档2
Document document2 = loadXmlDocument("C:\\abc\\dm-2-3.xml");
//创建Diff对象进行比较
diff = DiffBuilder.compare(document1)
.withTest(document2)
.checkForSimilar()
.build();
// 检查是否有差异
boolean hasDifferences = diff.hasDifferences();
if (hasDifferences) {
Iterable<Difference> differences = diff.getDifferences();
for (Difference difference : differences) {
// 获取差异的类型和详细信息,需要非空判断getControlDetails和getControlDetails由于结构和标签以及长度会为空不为空的时处理响应的标签内容
Comparison comparison = difference.getComparison();
ComparisonType type = comparison.getType();
String operation = ""; // 标记操作类型(增加、删除、修改)
String xPath = comparison.getControlDetails().getXPath();
Node controlNode = comparison.getControlDetails().getTarget(); // 获取控制节点的详细信息
Node testNode = comparison.getTestDetails().getTarget(); // 获取测试节点的详细信息
String controlTextContent = controlNode.getTextContent(); // 获取控制节点的文本内容
String testTextContent = testNode.getTextContent(); // 获取测试节点的文本内容
System.out.println("Difference in text content:");
System.out.println("Control Node Text Content: " + controlTextContent);
System.out.println("Test Node Text Content: " + testTextContent);
// 根据差异类型进行判断和标记操作类型
if (type == ComparisonType.CHILD_NODELIST_SEQUENCE) {
operation = "节点顺序差异";
} else if (type == ComparisonType.ELEMENT_NUM_ATTRIBUTES) {
operation = "属性数量差异";
} else if (type == ComparisonType.ATTR_NAME_LOOKUP) {
operation = "属性名称不匹配";
} else if (type == ComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED) {
operation = "属性值不匹配";
} else if (type == ComparisonType.DOCTYPE_NAME) {
operation = "元素标签名不匹配";
} else if (type == ComparisonType.TEXT_VALUE) {
operation = "文本值不匹配";
// 使用diff第一种只能用这种方式进行更新没有第二种好使
// Node node = getNodeByPath(document1, xPath);
// System.out.println(String.format("%s:%s", controlNode.getNodeName(), controlNode.getTextContent()));
// if (node != null && node.getNodeType() == Node.TEXT_NODE) {
// node.setTextContent("测试更新内容");
// saveXmlDocument(document1, "c:\\updated_xml2.xml");
// }
// String formattedControlValue = "<b font='color:red;'>" + controlTextContent + "</b>";
// if(!org.springframework.util.ObjectUtils.isEmpty(controlNode)) {
// if("#text".equals(controlNode.getNodeName())) {
// controlNode.setTextContent(formattedControlValue);
// System.out.println(String.format("%s:%s", controlNode.getNodeName(), controlNode.getTextContent()));
// }
//
// }
controlNode.setTextContent(testTextContent+"啦啦啦啦");
}
System.out.println(operation);
}
// 保存更新后的原始文档
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document1);
StreamResult result = new StreamResult(new File("c:\\updated.xml"));
transformer.transform(source, result);
System.out.println("XML document updated successfully.");
}
// 创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
// 使用DocumentBuilderFactory对象创建DocumentBuilder对象
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
// 创建一个空的Document对象
Document doc = dBuilder.newDocument();
// 将字符串内容转换为XML节点并添加到Document对象中
Document document = dBuilder.parse(new InputSource(new StringReader(control)));
Node targetRoot = document.getFirstChild();
doc.appendChild(doc.importNode(targetRoot, true));
// 将Document对象转换为字符串
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult result = new StreamResult(new File("output.xml"));
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(doc), new StreamResult(writer));
String output = writer.getBuffer().toString().replaceAll("\n|\r", "");
// 输出XML字符串
System.out.println(output);
}
}
// CHILD_NODELIST_SEQUENCE:表示子节点的顺序不同。
// ELEMENT_NUM_ATTRIBUTES:表示元素的属性数量不同。
// ATTR_NAME:表示属性名称不同。
// ATTR_VALUE_EXPLICITLY_SPECIFIED:表示属性值显式指定了,但是值不同。
// TEXT_VALUE:表示文本内容不同。
// NAMESPACE_PREFIX:表示命名空间前缀不同。
// NAMESPACE_URI:表示命名空间URI不同。
// COMMENT_VALUE:表示注释内容不同。
// PROCESSING_INSTRUCTION_TARGET:表示处理指令的目标不同。
// PROCESSING_INSTRUCTION_DATA:表示处理指令的数据不同。
// DOCTYPE_PUBLIC_ID:表示文档类型声明的公共标识符不同。
// DOCTYPE_SYSTEM_ID:表示文档类型声明的系统标识符不同。
// HAS_DOCTYPE_DECLARATION:表示一个文档有文档类型声明,而另一个没有。
// UNTYPED_ATTRIBUTE:表示未类型化的属性不同。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/200901.html