001package arcommon.xml; 002 003import java.io.ByteArrayInputStream; 004import java.io.File; 005import java.io.InputStream; 006import java.io.Serializable; 007import java.io.StringReader; 008import java.io.UnsupportedEncodingException; 009 010import javax.xml.parsers.DocumentBuilder; 011import javax.xml.parsers.DocumentBuilderFactory; 012import javax.xml.parsers.SAXParser; 013import javax.xml.parsers.SAXParserFactory; 014import javax.xml.xpath.XPath; 015import javax.xml.xpath.XPathConstants; 016import javax.xml.xpath.XPathExpression; 017import javax.xml.xpath.XPathExpressionException; 018import javax.xml.xpath.XPathFactory; 019 020import org.w3c.dom.Document; 021import org.w3c.dom.NamedNodeMap; 022import org.w3c.dom.Node; 023import org.w3c.dom.NodeList; 024import org.xml.sax.Attributes; 025import org.xml.sax.InputSource; 026import org.xml.sax.helpers.DefaultHandler; 027 028import arcommon.FileUtil; 029 030public class XmlUtil { 031 public static final String XML_ENCODING = "UTF-8"; 032 033 public static Document stringToDocument(String xml) { 034 try { 035 DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 036 InputSource is = new InputSource(); 037 is.setCharacterStream(new StringReader(xml)); 038 Document doc = db.parse(is); 039 return doc; 040 } catch (Exception e) { 041 throw new RuntimeException(e); 042 } 043 } 044 045 public static XPathExpression createXPathExpression(String xpathString) { 046 XPathFactory xPathFactory = XPathFactory.newInstance(); 047 XPath xpath = xPathFactory.newXPath(); 048 try { 049 XPathExpression xPathExpression = xpath.compile(xpathString); 050 return xPathExpression; 051 } catch (XPathExpressionException e) { 052 throw new RuntimeException(e); 053 } 054 } 055 056 public static NodeList selectNodes(String xml, String xpathString) { 057 Document doc = stringToDocument(xml); 058 XPathExpression xPathExpression = createXPathExpression(xpathString); 059 return selectNodes(doc, xPathExpression); 060 } 061 062 public static NodeList selectNodes(Document doc, String xpathString) { 063 XPathExpression xPathExpression = createXPathExpression(xpathString); 064 return selectNodes(doc, xPathExpression); 065 } 066 067 public static NodeList selectNodes(Document doc, XPathExpression xPathExpression) { 068 try { 069 NodeList nodes = ((NodeList) xPathExpression.evaluate(doc, XPathConstants.NODESET)); 070 return nodes; 071 } catch (XPathExpressionException e) { 072 throw new RuntimeException(e); 073 } 074 } 075 076 public static void printNode(Node node) { 077 printNode(node, ""); 078 } 079 080 private static void printNode(Node node, String indent) { 081 if (node.getLocalName() != null) { 082 System.out.println("node.getLocalName(): " + node.getLocalName()); 083 } 084 System.out.print(indent + "<"); 085 if (node.getNamespaceURI() != null) { 086 System.out.print(node.getNamespaceURI() + ":"); 087 } 088 System.out.print(node.getNodeName() + " "); 089 NamedNodeMap attributes = node.getAttributes(); 090 if (attributes != null) { 091 for (int i = 0; i < attributes.getLength(); i++) { 092 Node item = attributes.item(i); 093 System.out.print(item.getNodeName() + "=\"" + item.getNodeValue() + "\" "); 094 } 095 } 096 if (node.getNodeValue() != null && node.getNodeValue().length() > 0) { 097 System.out.print("node.getNodeValue()=\"" + encodeWhiteSpace(node.getNodeValue()) + "\" "); 098 } 099 if (node.getTextContent() != null && node.getTextContent().length() > 0 && !node.getTextContent().equals(node.getNodeValue())) { 100 System.out.print("node.getTextContent()=\"" + encodeWhiteSpace(node.getTextContent()) + "\" "); 101 } 102 NodeList childNodes = node.getChildNodes(); 103 if (childNodes != null && childNodes.getLength() > 0) { 104 System.out.println(">"); 105 106 for (int i = 0; i < childNodes.getLength(); i++) { 107 printNode(childNodes.item(i), indent + " "); 108 } 109 110 System.out.println(indent + "</" + node.getNodeName() + ">"); 111 } else { 112 System.out.println("/>"); 113 } 114 } 115 116 private static String encodeWhiteSpace(String string) { 117 string = string.replace("\r", "\\r"); 118 string = string.replace("\n", "\\n"); 119 string = string.replace("\t", "\\t"); 120 return string; 121 } 122 123 // Note: Doesn't read file encoding from XML 124 public static void saxParseFile(String fileName, DefaultHandler handler) { 125 try { 126 SAXParser saxParser = getSAXParser(); 127 saxParser.parse(new File(fileName), handler); 128 } catch (RuntimeException e) { 129 throw e; 130 } catch (Exception e) { 131 throw new RuntimeException(e); 132 } 133 } 134 135 // Doesn't work. Something is wrong with encoding 136/* public static void saxParseFileEncodingFromXml(String fileName, DefaultHandler handler) { 137 try { 138 File file = new File(fileName); 139 FileInputStream fileInputStream = new FileInputStream(file); 140 141 Reader inputStreamReader = new InputStreamReader(fileInputStream); 142 InputSource is = new InputSource(); 143 is.setCharacterStream(inputStreamReader); 144 145 saxParseInputSource(is, handler); 146 } catch (Exception e) { 147 System.out.println("XmlUtil.saxParseFile(): fileName: " + fileName); 148 throw new RuntimeException(e); 149 } 150 }*/ 151 152 public static void saxParseXml(String xml, DefaultHandler handler) { 153 InputStream stream; 154 try { 155 stream = new ByteArrayInputStream(xml.getBytes(XML_ENCODING)); 156 } catch (UnsupportedEncodingException e) { 157 throw new RuntimeException(e); 158 } 159 InputSource is = new InputSource(); 160 is.setByteStream(stream); 161 saxParseInputSource(is, handler); 162 } 163 164 public static SAXParser getSAXParser() { 165 try { 166 SAXParserFactory factory = SAXParserFactory.newInstance(); 167 SAXParser saxParser = factory.newSAXParser(); 168 return saxParser; 169 } catch (RuntimeException e) { 170 throw e; 171 } catch (Exception e) { 172 throw new RuntimeException(e); 173 } 174 } 175 176 public static void saxParseInputSource(InputSource is, DefaultHandler handler) { 177 try { 178 SAXParser saxParser = getSAXParser(); 179 saxParser.parse(is, handler); 180 } catch (RuntimeException e) { 181 throw e; 182 } catch (Exception e) { 183 throw new RuntimeException(e); 184 } 185 } 186 187 public static void objectToXmlFile(String fileName, Serializable object) { 188 String xml = objectToXmlString(object); 189 FileUtil.writeFile(fileName, xml, false, XML_ENCODING); 190 } 191 192 public static String objectToXmlString(Serializable object) { 193 XmlSerializer xmlSerializer = new XmlSerializer(); 194 String xml = xmlSerializer.objectToXmlString(object); 195 return xml; 196 } 197 198 public static Serializable xmlFileToObject(String fileName) { 199 XmlDeserializer xmlDeserializer = new XmlDeserializer(); 200 XmlUtil.saxParseFile(fileName, xmlDeserializer); 201 return xmlDeserializer.getResultObject(); 202 } 203 204 public static Serializable xmlStringToObject(String xml) { 205 XmlDeserializer xmlDeserializer = new XmlDeserializer(); 206 XmlUtil.saxParseXml(xml, xmlDeserializer); 207 return xmlDeserializer.getResultObject(); 208 } 209 210 public static String attributesToString(Attributes attributes) { 211 String result = ""; 212 for (int i = 0; i < attributes.getLength(); i++) { 213 if (result.length() > 0) { 214 result += " "; 215 } 216 result += attributes.getQName(i) + "=\"" + attributes.getValue(i) + "\""; 217 } 218 return result; 219 } 220 221 /** 222 * Encodes the string parameter in XML encoding (&name;). 223 * @see #decodeXmlString(String) 224 * @see arcommon.net.NetUtil#encodeUrlMyVariant(String) 225 * @see arcommon.net.NetUtil#decodeUrlToDisplayString(String) 226 */ 227 public static String encodeXmlString(String string) { 228 if (string == null) { 229 return null; 230 } 231 232 string = string.replace("&", "&"); 233 string = string.replace("<", "<"); 234 string = string.replace(">", ">"); 235 string = string.replace("\"", """); 236 string = string.replace("'", "'"); 237 238 return string; 239 } 240 241 /** 242 * Decodes the string parameter from XML encoding (&name;). 243 * @see #encodeXmlString(String) 244 * @see arcommon.net.NetUtil#encodeUrlMyVariant(String) 245 * @see arcommon.net.NetUtil#decodeUrlToDisplayString(String) 246 */ 247 public static String decodeXmlString(String string) { 248 if (string == null) { 249 return null; 250 } 251 252 string = string.replace("<", "<"); 253 string = string.replace(">", ">"); 254 string = string.replace(""", "\""); 255 string = string.replace("'", "'"); 256 string = string.replace("&", "&"); 257 258 return string; 259 } 260}