Files
Tools_java/xmltools/XMLTools.java
2025-02-05 09:40:38 +05:00

345 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tools.xml;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.SAXException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by IntelliJ IDEA.
* User: Igor
* Date: 18.12.2005
* Time: 15:26:59
* To change this template use File | Settings | File Templates.
*/
public class XMLTools
{
/**
* Вернуть значение первой попавшийся CDATA
* @return строка
*/
public static String getCDATAValue(Node node)
{
if(node==null) return "";
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals("#cdata-section"))
return n.getNodeValue();
}
return "";
}
public static Document parse(String xmlString) throws IOException, ParserConfigurationException, SAXException
{
return XMLIO.load(new ByteArrayInputStream(xmlString.getBytes()));
}
public static Document parse(InputStream xmlString) throws IOException, ParserConfigurationException, SAXException
{
return XMLIO.load(xmlString);
}
/**
* Возвращает вложенный элемент "childName" элемента "parent" <br/>
* &lt;element&gt;&lt;childName/&gt;&lt;/element&gt;
* @param parent
* @param childName
* @return Дочерный элемент либо <code>null</code>, если элементов с таким именем нет
*/
public static Element getChild(Element parent, String childName){
NodeList nl = parent.getChildNodes();
for (int i = 0; i <nl.getLength(); i++) {
if (isElement(nl.item(i), childName)){
return (Element)nl.item(i);
}
}
return null;
}
/**
* Проверяет, является ли <code>node</code> элементом (<code>instanceOf {@link Element}</code>)
* и имеет ли имя "tagname"
* @param node
* @param tagname
* @return
*/
public static boolean isElement(Node node, String tagname){
return node instanceof Element && node.getNodeName().equals(tagname);
}
/** Найти узел по атрибуту
*/
public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val)
{
if(node==null) return null;
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals(nodename))
{
NamedNodeMap nnm=n.getAttributes();
if(nnm.getNamedItem(attribute).getNodeValue().equals(val)) return n;
}
}
return null;
}
//вернуть первый попавшийся узел среди дочерних
public static Node getFirstNodeOnName(Node node,String nodename)
{
Node[] mas=new Node[50]; //depth
int pos=0;
mas[pos] = node.getFirstChild();
while (mas[pos] != null)
{
if(mas[pos].getNodeName().equals(nodename))
{
return mas[pos];
}
if(mas[pos].getFirstChild()!=null)
{
pos++;
mas[pos]=mas[pos-1].getFirstChild();
}else
{
//если не идёт дальше пытаемся подняться в верх по дереву
while (true)
{
mas[pos] = mas[pos].getNextSibling();
if (mas[pos]==null)
{
if(pos>0){ pos--; }else{ break; }
}else
{
break;
}
}
}
}
return null;
}
/**
* Return first from childs in first deep level on name
* @param node Find in
* @param nodename Name node
* @return node
*/
public static Node getNodeOnName(Node node,String nodename)
{
if(node==null) return null;
Node nextNode = node.getFirstChild();
while(nextNode != null)
{
if(nextNode.getNodeName().equals(nodename)) return nextNode;
nextNode=nextNode.getNextSibling();
}
return null;
}
//Сериализовать узел в строку
public static String getOuterXML(Node node)
{
DOMImplementationLS domImplementation = (DOMImplementationLS) node.getOwnerDocument().getImplementation();
LSSerializer lsSerializer = domImplementation.createLSSerializer();
if (!(node instanceof Document))
{
lsSerializer.getDomConfig().setParameter("xml-declaration", false);
}
return lsSerializer.writeToString(node);
}
/**
* Поиск среди текущего и дочерних узлов
* @param {Node} node Корневой узел
* @param {String} nodename Имя первого попавшегося узла
* @returns {undefined}
*/
public static Node findFirstNode(Node node, String nodename)
{
Node result=null;
if(node==null) return result;
javax.xml.xpath.XPathFactory xPathfactory = javax.xml.xpath.XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr=null;
Object exprResult=null;
try {
expr = xpath.compile("//*/"+nodename);
exprResult = expr.evaluate(node, XPathConstants.NODESET);
} catch (XPathExpressionException ex) {
}
NodeList nodeList = (NodeList) exprResult;
if (nodeList.getLength() > 0)
result = nodeList.item(0);
return result;
}
/**
* Найти узел по имени
* @param node
* @param nodename
* @return
*/
public static Node findFirstNode_v2(Node node, String nodename)
{
if(node==null || nodename==null) return null;
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals(nodename))
{
return n;
}
}
return null;
}
/** Найти узел по атрибуту
*/
public static Node findNodeOnAttribute(Node node, String nodename, String attribute, String val)
{
if(node==null) return null;
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals(nodename))
{
NamedNodeMap nnm=n.getAttributes();
if(nnm.getNamedItem(attribute).getNodeValue().equals(val)) return n;
}
}
return null;
}
public static Node findFirstNodeOnAttribute(Node node, String nodename,String attribute,String val)
{
Node result=null;
if(node==null) return result;
javax.xml.xpath.XPathFactory xPathfactory = javax.xml.xpath.XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr=null;
Object exprResult=null;
try {
expr = xpath.compile("//*/"+nodename+"[@"+attribute+"='" + val + "']");
exprResult = expr.evaluate(node, XPathConstants.NODESET);
} catch (XPathExpressionException ex) {
}
NodeList nodeList = (NodeList) exprResult;
if (nodeList.getLength() > 0)
result = nodeList.item(0);
return result;
}
/**
* Присвоить дочерние узлы первого дерева второму если их нет, иначе дополнить либо заменить. (Работает через рекурсию нужно для передачи параметров между окнами)
* @param {XML} first Узел где ханятся настройки
* @param {XML} second Узел к которому применяются настройки
* @param {String} name Имя атрибута по которому будут находиться одинаковые XML узлы
* @returns {undefined}
*/
public static void applyNodeToNode(Node first, Node second,String name)
{
if(first==null || second==null || name==null) return;
//Если есть совпадающие узлы то передаём в рекурсию если нет то просто копируем
Node fn=first.getFirstChild();
while (fn != null)
{
Node sn=null;
if(!fn.getNodeName().equals("#text") && !fn.getNodeName().equals("#cdata-section") && !fn.getNodeName().equals("#comment")) { //потому что для этих getAttribute вызывает ошибку
sn=findNodeOnAttribute(second,fn.getNodeName(),name,fn.getAttributes().getNamedItem(name).getNodeValue());
}
if(sn!=null) //Если по имени атрибуту совпали узлы
{
//Переписываем значения атрибутов из первого второму, если их нет то создаём.
for(int i=0;i<fn.getAttributes().getLength();i++)
{
Element el=(Element) sn;
el.setAttribute(fn.getAttributes().item(i).getNodeName(),fn.getAttributes().item(i).getNodeValue());
}
applyNodeToNode(fn,sn,name); //В рекурсию
}
else
{
//Значения CDADA или text node не должны накапливаться их мы пересоздаём (потом по момеру можно сделать 1й заменяется первым итд.)
if(fn.getNodeName().equals("#cdata-section"))
{
XMLTools.setCharacterDataToElement((Element)second, XMLTools.getCharacterDataFromElement((Element) fn)); //getCdata(second).nodeValue = fn.nodeValue;
}else
{
second.appendChild(fn.cloneNode(true));
}
}
fn=fn.getNextSibling();
}
}
/**
* Найти узел по имени
* @param node
* @param nodename
* @return
*/
public static Node findNode(Node node, String nodename)
{
if(node==null || nodename==null) return null;
NodeList items = node.getChildNodes();
for (int i=0;i<items.getLength();i++)
{
Node n=items.item(i);
if(n.getNodeName().equals(nodename))
{
return n;
}
}
return null;
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData().trim();
}
return "";
}
public static void setCharacterDataToElement(Node nF, String data) {
Node child = nF.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
cd.setData(data);
} else //Create new CDATA node
{
Document doc = nF.getOwnerDocument();
nF.appendChild(doc.createCDATASection(data));
}
}
}