package com.norteksoft.wf.base.utils; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jUtils { /** * 将file文件解析成Dom4j的文档 * @param file * @return */ public static Document getDocument(String file){ SAXReader reader = new SAXReader(); try { Document doc = reader.read(new ByteArrayInputStream(file.getBytes("UTF-8"))); return doc; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } /** * 根据子元素名称获取子元素 * @param parentElement * @param tagName * @return */ @SuppressWarnings("unchecked") public static Element getSubElementByName(Element parentElement, String tagName){ Element subElement = null; if(parentElement != null){ Iterator<Element> it = parentElement.elementIterator(); while(it.hasNext()){ subElement = it.next(); if(subElement.getName().equals(tagName)){ break; }else{ subElement = null; } } } return subElement; } /** * 根据子元素名称获取子元素集合 * @param tagName * @return */ @SuppressWarnings("unchecked") public List<Element> getSubElementsByName(Element parentElement, String tagName){ Iterator<Element> it = parentElement.elementIterator(); List<Element> subElements = new ArrayList<Element>(); Element subElement = null; while(it.hasNext()){ subElement = it.next(); if(subElement.getName().equals(tagName)){ subElements.add(subElement); } } return subElements; } /** * 移除root元素中所有的Tag名称为tagName元素 * @param root * @param tagName */ @SuppressWarnings("unchecked") public static void removeAllElementsByName(Element root, String tagName){ Iterator<Element> it = root.elementIterator(); Element subElement = null; while(it.hasNext()){ subElement = it.next(); if(subElement.getName().equals(tagName)){ root.remove(subElement); }else if(!subElement.isTextOnly()){ removeAllElementsByName(subElement, tagName); } } } /** * 从XML文档中根据路径获取元素值(从根路径开始,可以含有元素属性值) * @param xmlFile * @param path "/process/task[@name='name']" * @return */ public static String getSingleElementValueByPath(String processId, String path){ String result = null; if(StringUtils.isNotEmpty(WorkflowMemcachedUtil.getDefinitionFile(processId)) && StringUtils.isNotEmpty(path)){ path = path.replaceFirst("/", ""); String[] tags = path.split("/"); Element root = (DocumentParameterUtils.getDocument(processId)).getRootElement(); if(tags.length == 1){ result = root.getText(); }else{ Element element = getElementByPathAndProp(root, tags, 1); if(element != null){ result = element.getText(); } } } return result; } /** * 从XML文档中根据路径获取元素值(从根路径开始,可以含有元素属性值) * @param xmlFile * @param path "/process/task[@name='name']" * @return */ public static String getSingleElementPropByPath(String processId, String path, String propName){ String result = null; if(StringUtils.isNotEmpty(WorkflowMemcachedUtil.getDefinitionFile(processId)) && StringUtils.isNotEmpty(path)){ path = path.replaceFirst("/", ""); String[] tags = path.split("/"); Element root = (DocumentParameterUtils.getDocument(processId)).getRootElement(); if(tags.length == 1){ result = root.attributeValue(propName); }else{ Element element = getElementByPathAndProp(root, tags, 1); if(element != null){ result = element.attributeValue(propName); } } } return result; } @SuppressWarnings("unchecked") private static Element getElementByPathAndProp(Element root, String[] path, int pathIndex){ Element result = null; if(path[pathIndex].contains("[@")){ int propNameStart = path[pathIndex].indexOf("[@"); List<Element> subElements = root.elements(path[pathIndex].substring(0, propNameStart)); for(Element e : subElements){ int propNameEnd = path[pathIndex].indexOf("="); String propName = path[pathIndex].substring(propNameStart + 2, propNameEnd); int propValueStart = path[pathIndex].indexOf("'"); int propValueEnd = path[pathIndex].lastIndexOf("']"); String propValue = path[pathIndex].substring(propValueStart + 1, propValueEnd); if(propValue.equals(e.attributeValue(propName))){ result = e; break; } } }else{ result = root.element(path[pathIndex]); } if(result != null && ++pathIndex < path.length){ result = getElementByPathAndProp(result, path, pathIndex); } return result; } /** * 根据元素层级结构获取所需要的元素(path不包含root元素) * @param root * @param path parent:sub * @return */ public static Element getElementByPath(Element root, String path){ String[] tagNames = path.split(":"); Element result = getElementByPath(root, tagNames, 0); if(result != null && !result.getName().equals(tagNames[tagNames.length -1])){ result = null; } return result; } private static Element getElementByPath(Element root, String[] path, int index){ Element result = getSubElementByName(root, path[index]); if(result != null && ++index < path.length){ result = getElementByPath(result, path, index); } return result; } }