com.gdxsoft.easyweb.utils.UXml Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of emp-script-utils Show documentation
Show all versions of emp-script-utils Show documentation
Easy Web Appliaction Utils: UArgon2, UMail, UDigest, URsa,
UAes, UDes, UFile, UConvert, UFormat, UNet, SendMail, SmtpCfg
The newest version!
package com.gdxsoft.easyweb.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class UXml {
private static Logger LOGGER = LoggerFactory.getLogger(UXml.class);
/**
* Get XML Element all attributes
*
* @param item The element
* @param keyToLower nodeName to lower case
* @return Map <nodeName, nodeValue>
*/
public static Map getElementAttributes(Element item, boolean keyToLower) {
Map map = new HashMap<>();
for (int i = 0; i < item.getAttributes().getLength(); i++) {
Node att = item.getAttributes().item(i);
String name = keyToLower ? att.getNodeName().toLowerCase() : att.getNodeName();
String val = att.getNodeValue();
map.put(name, val);
}
return map;
}
/**
* 过滤非法的字符 0x00 - 0x08 ,0x0b - 0x0c ,0x0e - 0x1f
*
* @param xmlStr
* @return 过滤后的xml
*/
public static String filterInvalidXMLcharacter(String xmlStr) {
if (xmlStr == null || xmlStr.length() == 0) {
return xmlStr;
}
StringBuilder sb = new StringBuilder();
char[] chs = xmlStr.toCharArray();
for (char ch : chs) {
if ((ch >= 0x00 && ch <= 0x08) || (ch >= 0x0b && ch <= 0x0c) || (ch >= 0x0e && ch <= 0x1f)) {
// eat...
} else {
sb.append(ch);
}
}
return sb.toString();
}
/**
* 从Xml中查找某个节点
*
* @param fromNode
* @param findTag 要查找的TagName
* @param findAttr 检查的属性名称
* @param checkValue 检测值
* @param isIgnoreCase 是否大小写匹配
* @return 节点
*/
public static Element findNode(Element fromNode, String findTag, String findAttr, String checkValue,
boolean isIgnoreCase) {
NodeList nl = fromNode.getElementsByTagName(findTag);
for (int i = 0; i < nl.getLength(); i++) {
Element ele = (Element) nl.item(i);
String v = ele.getAttribute(findAttr);
if (isIgnoreCase) {
if (v.equalsIgnoreCase(checkValue)) {
return ele;
}
} else {
if (v.equals(checkValue)) {
return ele;
}
}
}
return null;
}
/**
* 生成可Xml节点值
*
* @param s1
* @return 节点值
*/
public static String createXmlValue(String s1) {
if (s1 == null)
return s1;
s1 = s1.replace("\r", "
");
s1 = s1.replace("\n", "
");
s1 = s1.replace("&", "&");
s1 = s1.replace("<", "<");
s1 = s1.replace(">", ">");
s1 = s1.replace("\"", """);
return s1;
}
/**
* 读取文件,返回 Document
*
* @param xmlPath xml文件路径
* @param isAbsolutePath 是否为绝对路径
* @return document 对象
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static Document retDocument(String xmlPath, boolean isAbsolutePath)
throws ParserConfigurationException, SAXException, IOException {
String p1 = xmlPath;
if (!isAbsolutePath) {
p1 = UPath.getScriptPath() + "/" + xmlPath;
}
return retDocument(p1);
}
/**
* 读取文件,返回 Document
*
* @param xmlPath xml文件路径
* @return document 对象
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static Document retDocument(String xmlPath) throws ParserConfigurationException, SAXException, IOException {
File f = new File(xmlPath);
Document doc = null;
if (!f.exists()) {
File fencode = new File(xmlPath + ".bin");
if (!fencode.exists()) {
throw new IOException("File not found!(" + f.getAbsolutePath());
}
byte[] encoderContent = null;
UAes des = null;
try {
des = UAes.getInstance();
} catch (Exception e1) {
throw new IOException("穿件解码出错!(" + e1.getMessage());
}
try {
encoderContent = UFile.readFileBytes(fencode.getAbsolutePath());
} catch (Exception e) {
throw new IOException("读取文件出错!(" + fencode.getAbsolutePath());
}
String xml;
try {
xml = des.decrypt(encoderContent).trim();
} catch (Exception e) {
throw new IOException("解码出错!(" + fencode.getAbsolutePath());
}
xml = UXml.filterInvalidXMLcharacter(xml);
doc = asDocument(xml);
} else {
URI u = f.toURI();
String uri = u.toASCIIString();
DocumentBuilderFactory factory = getDocumentBuilder();
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(uri);
}
return doc;
}
/**
* save xml document to file
*
* @param document Document对象
* @param xmlFileName 文件名
* @return 是否保存成功
*/
public static boolean saveDocument(Document document, String xmlFileName) {
String xml = UXml.asXmlAll(document);
try {
UFile.createNewTextFile(xmlFileName, xml);
return true;
} catch (Exception e) {
LOGGER.error("saveDocument", e);
return false;
}
}
/**
* 将 Document对象保存为文件
*
* @param document Document对象
* @return 是否保存成功
*/
public static boolean saveDocument(Document document) {
String xmlFileName = document.getDocumentURI().replace("file:///", "");
return saveDocument(document, xmlFileName);
}
/**
* 返回属性值
*
* @param node 当前节点
* @param attName 属性值
* @return 属性值
*/
public static String retNodeValue(Node node, String attName) {
if (node == null) {
return "";
}
if (node.getAttributes().getNamedItem(attName) == null) {
return "";
}
return node.getAttributes().getNamedItem(attName).getNodeValue();
}
/**
* 返回节点text
*
* @param node 当前节点
* @return TextContent
*/
public static String retNodeText(Node node) {
if (node == null) {
return null;
}
return node.getTextContent();
}
/**
* 返回下级节点集合
*
* @param document document对象
* @param tagName 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 集合
*/
public static NodeList retNodeList(Document document, String tagName) {
return retNodeListByPath(document, tagName);
}
/**
* 返回下级节点集合
*
* @param node node 对象
* @param tagName 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 集合
*/
public static NodeList retNodeList(Node node, String tagName) {
return retNodeListByPath(node, tagName);
}
/**
* 返回下级节点集合
*
* @param element element 对象
* @param tagName 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 集合
*/
public static NodeList retNodeList(Element element, String tagName) {
return retNodeListByPath(element, tagName);
}
/**
* 返回下级节点
*
* @param node node对象
* @param tagName 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 下级节点
*/
public static Node retNode(Node node, String tagName) {
return retNode((Element) node, tagName);
}
/**
* 返回下级节点
*
* @param document
* @param tagName 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 下级节点
*/
public static Node retNode(Document document, String tagName) {
if (document == null)
return null;
return retNode(document.getDocumentElement(), tagName);
}
/**
* 返回下级节点
*
* @param element
* @param tagName 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 下级节点
*/
public static Node retNode(Element element, String tagName) {
NodeList nl = retNodeList(element, tagName);
if (nl == null) {
return null;
}
return nl.item(0);
}
/**
* 返回节点列表通过路径
*
* @param element element 元素
* @param tagPath 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 列表
*/
public static NodeList retNodeListByPath(Element element, String tagPath) {
if (tagPath == null || element == null)
return null;
String[] s1 = tagPath.split("/");
Element ele = element;
for (int i = 0; i < s1.length - 1; i++) {
Node node = retNode(ele, s1[i]);
if (node == null)
return null;
ele = (Element) node;
}
return ele.getElementsByTagName(s1[s1.length - 1]);
}
/**
* 返回节点列表通过路径
*
* @param document document对象
* @param tagPath 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 列表
*/
public static NodeList retNodeListByPath(Document document, String tagPath) {
if (document == null)
return null;
String[] a = tagPath.split("/");
if (a.length == 1) {
if (document.getFirstChild().getNodeName().equals(a[0])) {
return document.getChildNodes();
} else {
return null;
}
}
Element ele = document.getDocumentElement();
String s2 = "";
for (int i = 1; i < a.length; i++) {
if (i == 1) {
s2 = a[1];
} else {
s2 = s2 + "/" + a[i];
}
}
return retNodeListByPath(ele, s2);
}
/**
* 返回节点列表通过路径
*
* @param node 父节点
* @param tagPath 下级节点表达式,例如 aa/bb/cc,返回 aa<bb<cc
* @return 节点列表
*/
public static NodeList retNodeListByPath(Node node, String tagPath) {
return retNodeListByPath((Element) node, tagPath);
}
/**
* 增加节点
*
* @param document
* @param newChilid
* @param tagPathParent
* @return 是否成功
*/
public static boolean addNode(Document document, Element newChilid, String tagPathParent) {
Node parentNode = retNodeListByPath(document, tagPathParent).item(0);
if (parentNode == null)
return false;
parentNode.appendChild(newChilid);
return true;
}
/**
* 删除节点
*
* @param document
* @param tagPath
* @param nodeAttribute
* @param attValue
* @return 是否成功
*/
public static boolean removeNode(Document document, String tagPath, String nodeAttribute, String attValue) {
NodeList nodes = retNodeListByPath(document, tagPath);
if (nodes == null)
return false;
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
String v1 = retNodeValue(node, nodeAttribute);
if (v1.equals(attValue)) {
node.getParentNode().removeChild(node);
return true;
}
}
return false;
}
/**
* 获取配置文件的节点
*
* @param xmlName 文件路径
* @param itemName 节点名称
* @param tagPath 路径
* @return 节点
* @throws IOException
* @throws SAXException
* @throws ParserConfigurationException
*/
public static Node queryNode(String xmlName, String itemName, String tagPath)
throws ParserConfigurationException, SAXException, IOException {
Document doc = retDocument(xmlName);
return queryNode(doc, "Name", itemName, tagPath);
}
/**
* 获取配置文件的节点
*
* @param document xml文档
* @param itemName 节点名称
* @param tagPath 路径
* @return 节点
*/
public static Node queryNode(Document document, String itemName, String tagPath) {
return queryNode(document, "Name", itemName, tagPath);
}
/**
* 获取配置文件的节点
*
* @param document xml文档
* @param attributeName 属性名
* @param itemName 节点名称
* @param tagPath 路径
* @return 节点
*/
public static Node queryNode(Document document, String attributeName, String itemName, String tagPath) {
NodeList nl = retNodeListByPath(document, tagPath);
if (nl == null)
return null;
for (int i = 0; i < nl.getLength(); i++) {
Node node = (Node) nl.item(i);
String name = retNodeValue(node, attributeName);
if (name == null)
continue;
if (name.toUpperCase().trim().equals(itemName.toUpperCase().trim())) {
return node;
}
}
return null;
}
/**
* 返回Xml字符,不包含 <?xml version="1.0" encoding="UTF-8"?>
*
* @param node 节点
* @return Xml字符串
*/
public static String asXml(Node node) {
String xml = asXmlAll(node);
if (xml != null) {
int m0 = xml.indexOf("", m0);
if (m1 > m0 && m0 >= 0) {
xml = xml.substring(m1 + 2);
}
}
return xml;
}
/**
* 美化Xml输出
*
* @param node 节点
* @return Xml字符串
*/
public static String asXmlPretty(Node node) {
TransformerFactory tf = TransformerFactory.newInstance();
Integer i2 = 2;
tf.setAttribute("indent-number", i2);
// (2)
Transformer t;
ByteArrayOutputStream out = new ByteArrayOutputStream();
String s1 = "";
try {
t = tf.newTransformer();
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(node), new StreamResult(new OutputStreamWriter(out, "utf-8")));
s1 = out.toString("utf-8");
return s1;
} catch (TransformerConfigurationException e) {
return e.getMessage();
} catch (UnsupportedEncodingException e) {
return e.getMessage();
} catch (TransformerException e) {
return e.getMessage();
}
}
/**
* 返回 Xml字符串 ,包含 <?xml version="1.0" encoding="UTF-8"?>
*
* @param node
* @return Xml字符串
*/
public static String asXmlAll(Node node) {
TransformerFactory l_transformFactory = TransformerFactory.newInstance();
Transformer l_transformer = null;
ByteArrayOutputStream l_byteOutStream = new ByteArrayOutputStream();
String s1 = "";
try {
l_transformer = l_transformFactory.newTransformer();
l_transformer.transform(new DOMSource(node), new StreamResult(l_byteOutStream));
s1 = l_byteOutStream.toString("utf-8");
} catch (Exception e) {
System.err.println(e.getMessage());
return null;
} finally {
try {
l_byteOutStream.close();
} catch (IOException e) {
}
}
return s1;
}
/**
* 将xml字符串转换为 node
*
* @param xmlSource
* @return node
*/
public static Node asNode(String xmlSource) {
Document doc = asDocument(xmlSource);
if (doc == null)
return null;
return doc.getFirstChild();
}
/**
* 获取安全的 DocumentBuilderFactory,避免XXE攻击
*
* @return DocumentBuilderFactory
*/
public static DocumentBuilderFactory getDocumentBuilder() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 避免 XXE 注入攻击 郭磊 2018-07-05
factory.setExpandEntityReferences(false);
return factory;
}
/**
* 从xml字符串中返回XmlDocument对象
*
* @param xmlSource xml字符串
* @return Document
*/
public static Document asDocument(String xmlSource) {
DocumentBuilderFactory factory = getDocumentBuilder();
DocumentBuilder builder;
StringReader sr = new StringReader(xmlSource);
InputSource is = new InputSource(sr);
is.setEncoding("utf-8");
try {
builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);
return doc;
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
return null;
} catch (SAXException e) {
System.out.println(e.getMessage());
return null;
} catch (IOException e) {
System.out.println(e.getMessage());
return null;
} finally {
sr.close();
}
}
/**
* 创建并返回空白的xml文档
*
* @return Document
*/
public static Document createBlankDocument() {
DocumentBuilderFactory factory = getDocumentBuilder();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
return doc;
} catch (ParserConfigurationException e) {
System.err.println(e.toString());
return null;
}
}
/**
* 生成空xml文档,并保存为文件
*
* @param path xml路径
* @return xml文档
*/
public static Document createSavedDocument(String path, String rootTagName) {
String s1 = "";
s1 += "<" + rootTagName + ">" + rootTagName + ">";
try {
UFile.createNewTextFile(path, s1);
Document d = retDocument(path);
return d;
} catch (Exception e) {
System.err.println(e.getMessage());
return null;
}
}
/**
* 生成空文件
*
* @param dtd dtd文件
* @param qName qName
* @return Document
*/
public static Document createBlankDocument(String dtd, String qName) {
DocumentBuilderFactory factory = getDocumentBuilder();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
DOMImplementation impl = builder.getDOMImplementation();
DocumentType type = impl.createDocumentType(qName, "SYSTEM", dtd);
Document doc = impl.createDocument(qName, qName, type);
return doc;
} catch (ParserConfigurationException e) {
System.err.println(e.toString());
e.printStackTrace();
return null;
}
}
/**
* 在Xml文档中增加新的节点
*
* @param sourceDocument 源文档
* @param nodeXmlString node的Xml字符
* @param tagPath 增加的路径
* @return 新文档
*/
public static Document appendNode(Document sourceDocument, String nodeXmlString, String tagPath) {
String xml = asXml(sourceDocument.getDocumentElement());
String[] a1 = tagPath.split("/");
int m = 0;
for (int i = 0; i < a1.length; i++) {
if (m < 0) {
return null;
}
m = xml.indexOf("<" + a1[i], m);
int m1 = xml.indexOf("" + a1[i] + ">", m);
if (m1 < 0) {
m1 = xml.indexOf("/>", m);
if (m1 > 0) {
xml = xml.substring(0, m1) + ">" + a1[i] + ">" + xml.substring(m1 + 2);
} else {
return null;
}
m = xml.indexOf("" + a1[i] + ">", m);
} else {
m = m1;
}
}
// 不要用字符串,可能会内存溢出
StringWriter sw = new StringWriter();
sw.write(xml.substring(0, m));
sw.write(nodeXmlString);
sw.write(xml.substring(m));
Node n1 = asNode(sw.toString());
try {
sw.close();
} catch (Exception e) {
System.err.println(e.toString());
}
sw = null;
if (n1 == null)
return null;
Document newDoc = n1.getOwnerDocument();
return newDoc;
}
}