| /******************************************************************************* |
| * Copyright (c) 2004, 2007 Boeing. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Boeing - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.osee.framework.jdk.core.util.xml; |
| |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.StringWriter; |
| import java.io.Writer; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.LinkedList; |
| import java.util.List; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamWriter; |
| import javax.xml.transform.Result; |
| import javax.xml.transform.Source; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| 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 org.apache.xml.serialize.OutputFormat; |
| import org.apache.xml.serialize.XMLSerializer; |
| import org.eclipse.osee.framework.jdk.core.util.Strings; |
| import org.eclipse.osee.framework.jdk.core.util.io.CharBackedInputStream; |
| import org.w3c.dom.Attr; |
| 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.ProcessingInstruction; |
| import org.w3c.dom.Text; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| public class Jaxp { |
| private static final DocumentBuilderFactory namespceUnawareFactory = DocumentBuilderFactory.newInstance(); |
| private static final DocumentBuilderFactory namespceAwareFactory = DocumentBuilderFactory.newInstance(); |
| static { |
| namespceAwareFactory.setNamespaceAware(true); |
| } |
| |
| /** |
| * Obtains a list of all direct descendants of element |
| * |
| * @param element the element to find the children of |
| * @return A list of elements that are direct children of element. If no children exist, an empty list is returned. |
| */ |
| public static List<Element> getChildDirects(Element element) { |
| NodeList nl = element.getChildNodes(); |
| List<Element> elementList = new ArrayList<Element>(nl.getLength()); // this may be oversized |
| for (int i = 0; i < nl.getLength(); i++) { |
| Node n = nl.item(i); |
| if (n.getNodeType() == Node.ELEMENT_NODE) { |
| elementList.add((Element) n); |
| } |
| } |
| return elementList; |
| } |
| |
| /** |
| * Obtains a list of all direct descendants of element with the matching tag. |
| * |
| * @param element the element to find the children of |
| * @param childTagName the tag name for the children |
| * @return A list of elements that are direct children of element whose tag names match childTagName. If no such |
| * children exist, an empty list is returned. |
| */ |
| public static List<Element> getChildDirects(Element element, String childTagName) { |
| List<Element> elementList = new ArrayList<Element>(); |
| NodeList nl = element.getChildNodes(); |
| for (int i = 0; i < nl.getLength(); i++) { |
| Node n = nl.item(i); |
| if (n.getNodeType() == Node.ELEMENT_NODE && ((Element) n).getTagName().equals(childTagName)) { |
| elementList.add((Element) n); |
| } |
| } |
| return elementList; |
| } |
| |
| /** |
| * Obtains the first child that is a direct descendant of element with the matching tag |
| * |
| * @param element the element to find the child of |
| * @param childTagName the tag name for the child |
| * @return the first child with the given tag one level deep from element, null if no such child exists. |
| */ |
| public static Element getChildDirect(Element element, String childTagName) { |
| NodeList nl = element.getChildNodes(); |
| for (int i = 0; i < nl.getLength(); i++) { |
| Node n = nl.item(i); |
| if (n.getNodeType() == Node.ELEMENT_NODE && ((Element) n).getTagName().equals(childTagName)) { |
| return (Element) n; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Obtains the first child that is a descendant of element with the matching tag |
| * |
| * @param element the element to find the child of |
| * @param childTagName the tag name for the child |
| * @return the first child with the given tag, or null if no such children exist |
| */ |
| public static Element getChild(Element element, String childTagName) { |
| NodeList elementList = element.getElementsByTagName(childTagName); |
| return (Element) elementList.item(0); |
| } |
| |
| public static Element createElement(Document d, String tag, String characterData) { |
| Element e = d.createElement(tag); |
| Text t = d.createTextNode(characterData); |
| e.appendChild(t); |
| // e.setTextContent(characterData); |
| // the above two lines do the same thing as this, but I trust them more so we'll go that |
| // route. |
| return e; |
| } |
| |
| /** |
| * Obtains the character data for the Element. Note this differs from the Node.getTextContext(); call, which returns |
| * the concatenation of the character data for all children of this Element. |
| * |
| * @param e The element go get the character data for |
| * @param trimWhitespace if true, each segment will be trimmed. |
| * @return All of the character data for the Element e. This means if there are elements separating the character |
| * data, it will all be concatenated together. If trimWhitespace, each segment will be trimmed of whitespace, with a |
| * single space between segments; otherwise the segments will be concatenated without any space separation. If no |
| * character data is present, returns an empty string. |
| */ |
| public static String getElementCharacterData(Element e, boolean trimWhitespace) { |
| NodeList childNodes = e.getChildNodes(); |
| StringBuilder resultString = new StringBuilder(); |
| boolean first = true; |
| |
| for (int i = 0; i < childNodes.getLength(); i++) { |
| Node n = childNodes.item(i); |
| if (n.getNodeType() == Node.TEXT_NODE) { |
| if (!first && trimWhitespace) { |
| resultString.append(" "); |
| } |
| resultString.append(trimWhitespace ? n.getNodeValue().trim() : n.getNodeValue()); |
| first = false; |
| } else if (n.getNodeType() == Node.CDATA_SECTION_NODE) { |
| if (!first && trimWhitespace) { |
| resultString.append(" "); |
| } |
| resultString.append(trimWhitespace ? n.getNodeValue().trim() : n.getNodeValue()); |
| first = false; |
| } |
| } |
| return resultString.toString(); |
| } |
| |
| /** |
| * Obtains the character data for the Element. Note this differs from the Node.getTextContext(); call, which returns |
| * the concatenation of the character data for all children of this Element. |
| * |
| * @param e The element go get the character data for |
| * @return All of the character data for the Element e. This means if there are elements separating the character |
| * data, it will all be concatenated together. Each segment will be trimmed of whitespace, with a single space |
| * between segments. If no character data is present, returns an empty string. |
| */ |
| public static String getElementCharacterData(Element e) { |
| return getElementCharacterData(e, true); |
| } |
| |
| /** |
| * Obtains the character data for each element in the collection, return as a List. Each entry in the list |
| * corresponding to the character data for one of the elements in the collection. |
| */ |
| public static List<String> getElementsCharacterData(Collection<Element> elements) { |
| List<String> result = new ArrayList<String>(elements.size()); |
| for (Element e : elements) { |
| result.add(Jaxp.getElementCharacterData(e)); |
| } |
| return result; |
| } |
| |
| /** |
| * @param nodes The NodeList whose text we will return |
| * @return An ArrayList<String> of the text for all nodes |
| */ |
| public static ArrayList<String> getChildrenTexts(NodeList nodes) { |
| ArrayList<String> retVal = new ArrayList<String>(nodes.getLength()); |
| |
| for (int i = 0; i < nodes.getLength(); i++) { |
| Element element = (Element) nodes.item(i); |
| retVal.add(getElementCharacterData(element)); |
| } |
| return retVal; |
| } |
| |
| /** |
| * Obtains a list of Strings of the character data for all elements in the document whose tag name matches. |
| * |
| * @param document The document to be searched |
| * @param tagName The tagName for the children whose text we will obtain |
| * @return An ArrayList<String> of the text for all child nodes matching tagName |
| */ |
| public static ArrayList<String> getChildrenTexts(Document document, String tagName) { |
| return getChildrenTexts(document.getElementsByTagName(tagName)); |
| } |
| |
| /** |
| * Obtains a list of Strings of the character data for all descendants of element whose tag name matches. |
| * |
| * @param document The document to be searched |
| * @param tagName The tagName for the children whose text we will obtain |
| * @return An ArrayList<String> of the text for all child nodes matching tagName |
| */ |
| public static ArrayList<String> getChildrenTexts(Element element, String tagName) { |
| return getChildrenTexts(element.getElementsByTagName(tagName)); |
| } |
| |
| public static String getChildText(Element element, String childTagName, boolean trim) { |
| Element child = getChild(element, childTagName); |
| if (child != null) { |
| return getElementCharacterData(child, trim); |
| } |
| return null; |
| } |
| |
| public static String getChildText(Element element, String childTagName) { |
| return getChildText(element, childTagName, false); |
| } |
| |
| public static String getChildTextTrim(Element element, String childTagName) { |
| return getChildText(element, childTagName, true); |
| } |
| |
| private static void findElementsInternal(List<Element> source, LinkedList<String> path, List<Element> list) { |
| String tag = path.poll(); |
| LinkedList<String> childPath = new LinkedList<String>(path); |
| |
| for (Element e : source) { |
| List<Element> children = getChildDirects(e, tag); |
| if (!children.isEmpty()) { |
| if (path.isEmpty()) { |
| list.addAll(children); |
| } else { |
| findElementsInternal(children, childPath, list); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Searches for all sub-elements found at the path provided. |
| * |
| * @param element The element underneath which we will search |
| * @param elementPath The path to follow. For example ["script","configuration","element_i_want"] |
| * @param firstIsRoot If true, the first item in elementPath must match element. That is, in the above example, e's |
| * tag name must be "script". This is useful when calling from the document level, that is where element is |
| * Document.getDocumentElement(), the first item in the path would be the first root element of the xml tree. |
| * @return All elements that match the specified path. |
| */ |
| public static List<Element> findElements(Element element, List<String> elementPath, boolean firstIsRoot) { |
| List<Element> result = new LinkedList<Element>(); |
| List<Element> source = new ArrayList<Element>(1); |
| source.add(element); |
| |
| LinkedList<String> path; |
| if (elementPath instanceof LinkedList<?>) { |
| path = (LinkedList<String>) elementPath; |
| } else { |
| path = new LinkedList<String>(elementPath); |
| } |
| |
| // Strip off the first item of elementPath and make sure it matches 'element' |
| if (firstIsRoot) { |
| String firstTagName = path.poll(); |
| if (element.getTagName().equals(firstTagName)) { |
| return result; |
| } |
| } |
| |
| findElementsInternal(source, path, result); |
| return result; |
| } |
| |
| private static List<Element> findElementsSinglePath(Element e, String elementPath, boolean firstIsRoot) { |
| return findElements(e, Arrays.asList(elementPath.split("/")), firstIsRoot); |
| } |
| |
| private static List<Element> findElements(Element e, String elementPath, boolean firstIsRoot) { |
| List<Element> result = new LinkedList<Element>(); |
| String[] paths = elementPath.split("\\|"); |
| |
| for (String path : paths) { |
| result.addAll(findElementsSinglePath(e, path, firstIsRoot)); |
| } |
| return result; |
| } |
| |
| public static List<Element> findElements(Element element, String elementPath) { |
| return findElements(element, elementPath, false); |
| } |
| |
| public static List<Element> findElements(Document d, String elementPath) { |
| return findElements(d.getDocumentElement(), elementPath, true); |
| } |
| |
| /** |
| * Searches for a sub-element found at the path provided. Each list element indicates the tag name for the next |
| * sub-element. |
| * |
| * @param e The element underneath which we will search |
| * @param elementPath The path to follow. For example ["script","configuration","element_i_want"] |
| * @return The first element that matches the provided path, beneath the provided element e, or null if no such |
| * element exists. |
| */ |
| public static Element findElement(Element element, List<String> elementPath) { |
| |
| Element e = element; |
| for (String tag : elementPath) { |
| NodeList a = e.getChildNodes(); |
| Element nextElement = null; |
| for (int i = 0; i < a.getLength() && nextElement == null; i++) { |
| Node n = a.item(i); |
| if (n.getNodeType() == Node.ELEMENT_NODE && ((Element) n).getTagName().equals(tag)) { |
| nextElement = (Element) n; |
| } |
| } |
| if (nextElement == null) { |
| return null; |
| } else { |
| e = nextElement; |
| } |
| } |
| return e; |
| } |
| |
| /** |
| * Searches the Document for the Element found at the '/' delimited path provided. The path should begin with the |
| * root node of the document. |
| * |
| * @param d The document to search |
| * @param elementPath The path to follow. For example "script/configuration/element_i_want" |
| * @return The first element that matches the provided path, or null if no such element exists. |
| */ |
| public static Element findElement(Document d, String elementPath) { |
| List<String> pathList = Arrays.asList(elementPath.split("/")); |
| String rootTagName = pathList.get(0); |
| // Remove the first item from the list, Arrays.asList List type doesn't support .remove() |
| if (pathList.size() > 1) { |
| pathList = pathList.subList(1, pathList.size()); |
| } else { |
| pathList.clear(); |
| } |
| |
| Element root = d.getDocumentElement(); |
| if (!root.getTagName().equals(rootTagName)) { |
| return null; |
| } |
| return findElement(d.getDocumentElement(), pathList); |
| } |
| |
| /** |
| * Searches for a sub-element found at the '/' delimited path provided. The path should begin with the first node |
| * underneath the provided element. |
| * |
| * @param e The element underneath which we will search |
| * @param elementPath The path to follow. For example "script/configuration/element_i_want" |
| * @return The first element that matches the provided path, beneath the provided element e, or null if no such |
| * element exists. |
| */ |
| public static Element findElement(Element e, String elementPath) { |
| return findElement(e, Arrays.asList(elementPath.split("/"))); |
| } |
| |
| @Deprecated |
| public static Document readXmlDocument(InputStream is) throws ParserConfigurationException, SAXException, IOException { |
| return readXmlDocument(is, "UTF-8"); |
| } |
| |
| public static Document readXmlDocument(InputStream is, String encoding) throws ParserConfigurationException, SAXException, IOException { |
| InputSource inputSource = new InputSource(is); |
| inputSource.setEncoding(encoding); |
| DocumentBuilder builder = namespceUnawareFactory.newDocumentBuilder(); |
| return builder.parse(inputSource); |
| } |
| |
| public static Document readXmlDocument(String xmlString) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceUnawareFactory.newDocumentBuilder(); |
| CharBackedInputStream charBak = new CharBackedInputStream(); |
| charBak.addBackingSource(xmlString); |
| Document document = builder.parse(charBak); |
| return document; |
| } |
| |
| public static Document readXmlDocument(File xmlFile) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceUnawareFactory.newDocumentBuilder(); |
| Document document = builder.parse(xmlFile); |
| return document; |
| } |
| |
| public static Document readXmlDocumentFromResource(Class<?> base, String name) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceUnawareFactory.newDocumentBuilder(); |
| Document document = builder.parse(base.getResourceAsStream(name)); |
| return document; |
| } |
| |
| public static Document readXmlDocumentNamespaceAware(InputStream is) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceAwareFactory.newDocumentBuilder(); |
| return builder.parse(is); |
| } |
| |
| public static Document readXmlDocumentNamespaceAware(String xmlString) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceAwareFactory.newDocumentBuilder(); |
| CharBackedInputStream charBak = new CharBackedInputStream(); |
| charBak.addBackingSource(xmlString); |
| Document document = builder.parse(charBak); |
| return document; |
| } |
| |
| public static Document readXmlDocumentNamespaceAware(File xmlFile) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceAwareFactory.newDocumentBuilder(); |
| |
| Document document = builder.parse(xmlFile); |
| return document; |
| } |
| |
| public static Document readXmlDocumentFromResourceNamespaceAware(Class<?> base, String name) throws ParserConfigurationException, SAXException, IOException { |
| DocumentBuilder builder = namespceAwareFactory.newDocumentBuilder(); |
| Document document = builder.parse(base.getResourceAsStream(name)); |
| return document; |
| } |
| |
| /** |
| * Adds the XSL style sheet processing instruction to the document. |
| */ |
| public static void setXslProperty(Document d, String xslPath) { |
| ProcessingInstruction xsl = d.createProcessingInstruction("xml-stylesheet", // |
| "type=\"text/xsl\" href=\"" + xslPath + "\""); |
| d.appendChild(xsl); |
| } |
| |
| /** |
| * Adds an XML comment to a document |
| */ |
| public static void addComment(Document d, String comment) { |
| d.appendChild(d.createComment(comment)); |
| d.getChildNodes().item(0); |
| } |
| |
| public static void prependComment(Document d, String comment) { |
| Node commentNode = d.createComment(comment); |
| |
| Node firstNode = getChild(d.getDocumentElement(), "TestScript"); |
| d.insertBefore(commentNode, firstNode); |
| } |
| |
| /** |
| * Writes the XML document 'document' to the 'file'. |
| * |
| * @param document The XML document to output |
| * @param file Where to put the output |
| */ |
| public static void writeXmlDocument(Document document, File file) throws TransformerException, IOException { |
| writeXmlDocument(document, file, getCompactFormat(document)); |
| } |
| |
| /** |
| * Writes the XML document 'document' to the 'file'. |
| * |
| * @param document The XML document to output |
| * @param file Where to put the output |
| * @param prettyOutput If true, turns on indention so the output is more easily readable, if False turns indention |
| * off to save space. |
| */ |
| public static void writeXmlDocument(Document document, File file, OutputFormat format) throws TransformerException, IOException { |
| BufferedWriter out = new BufferedWriter(new FileWriter(file)); |
| outputXmlDocument(document, out, format); |
| out.close(); |
| } |
| |
| /** |
| * Gets the XML document 'document' as a string |
| * |
| * @param document The XML document to output |
| * @param file Where to put the output |
| * @param prettyOutput If true, turns on indention so the output is more easily readable, if False turns indention |
| * off and is assumed to provide the XML as compactly as possible. |
| */ |
| public static String xmlToString(Document document, OutputFormat format) throws IOException { |
| StringWriter stringWriter = new StringWriter(); |
| outputXmlDocument(document, stringWriter, format); |
| return stringWriter.toString(); |
| } |
| |
| /** |
| * Sends the XML to the output |
| * |
| * @param document The source XML |
| * @param output Where the XML is 'printed' to |
| * @param format The format style to use |
| */ |
| private static void outputXmlDocument(Document document, Writer output, OutputFormat format) throws IOException { |
| XMLSerializer serializer = new XMLSerializer(output, format); |
| serializer.serialize(document); |
| } |
| |
| /** |
| * Generates an OutputFormat that is pleasing to look at (indention, newlines, etc) |
| * |
| * @param document the document to be formatted |
| * @return the OutputFormat object to use for XML Formatting |
| * @see XMLSerializer |
| */ |
| public static OutputFormat getPrettyFormat(Document document) { |
| OutputFormat format = new OutputFormat(document); |
| format.setIndenting(true); |
| format.setIndent(2); |
| return format; |
| } |
| |
| /** |
| * Generates an OutputFormat that is compact (no extra whitepsace) |
| * |
| * @param document the document to be formatted |
| * @return the OutputFormat object to use for XML Formatting |
| * @see XMLSerializer |
| */ |
| public static OutputFormat getCompactFormat(Document document) { |
| OutputFormat format = new OutputFormat(document); |
| format.setIndenting(false); |
| format.setLineSeparator(""); |
| return format; |
| } |
| |
| /** |
| * @deprecated Use {@link #newDocumentNamespaceAware()} instead |
| */ |
| @Deprecated |
| public static Document newDocument() throws ParserConfigurationException { |
| return newDocumentNamespaceAware(); |
| } |
| |
| public static Document newDocumentNamespaceAware() throws ParserConfigurationException { |
| DocumentBuilder builder = namespceAwareFactory.newDocumentBuilder(); |
| return builder.newDocument(); |
| } |
| |
| public static String getDocumentXml(Document doc) throws TransformerException { |
| Source source = new DOMSource(doc); |
| StringWriter stringWriter = new StringWriter(); |
| Result result = new StreamResult(stringWriter); |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| Transformer transformer = factory.newTransformer(); |
| transformer.transform(source, result); |
| return stringWriter.getBuffer().toString(); |
| } |
| |
| public static final String selectNodesText(Node startingNode) { |
| StringBuffer buffer = new StringBuffer(); |
| NodeList childNodes = startingNode.getChildNodes(); |
| for (int i = 0; i < childNodes.getLength(); i++) { |
| if (childNodes.item(i).getNodeType() == Node.CDATA_SECTION_NODE || childNodes.item(i).getNodeType() == Node.TEXT_NODE) { |
| buffer.append(childNodes.item(i).getNodeValue().trim()); |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| public static final Collection<Node> selectNodesViaXPath(XPath xPath, Node startingNode, String xPathExpression) throws XPathExpressionException { |
| Collection<Node> data = new ArrayList<Node>(); |
| XPathExpression expression = xPath.compile(xPathExpression); |
| Object result = expression.evaluate(startingNode, XPathConstants.NODESET); |
| NodeList nodeList = (NodeList) result; |
| for (int index = 0; index < nodeList.getLength(); index++) { |
| data.add(nodeList.item(index)); |
| } |
| return data; |
| } |
| |
| public static XPath createXPath() { |
| XPathFactory factory = XPathFactory.newInstance(); |
| return factory.newXPath(); |
| } |
| |
| public static void writeNode(XMLStreamWriter writer, Node node, boolean trimTextNodeWhitespace) throws XMLStreamException { |
| if (node instanceof Element) { |
| Element element = (Element) node; |
| |
| String namespace = element.getNamespaceURI(); |
| String prefix = element.getPrefix(); |
| String name = element.getLocalName(); |
| if (!Strings.isValid(name)) { |
| name = element.getNodeName(); |
| } |
| if (Strings.isValid(name)) { |
| if (prefix != null && namespace != null) { |
| writer.writeStartElement(prefix, name, namespace); |
| // } else if (namespace != null) { |
| // writer.writeStartElement("", namespace, name); |
| } else { |
| writer.writeStartElement(name); |
| } |
| |
| if (node.hasAttributes()) { |
| NamedNodeMap nodeMap = node.getAttributes(); |
| for (int index = 0; index < nodeMap.getLength(); index++) { |
| writeAttrNode(writer, nodeMap.item(index)); |
| } |
| } |
| |
| if (node.hasChildNodes()) { |
| serialize(writer, element.getChildNodes(), trimTextNodeWhitespace); |
| } |
| |
| String data = Jaxp.getElementCharacterData(element, trimTextNodeWhitespace); |
| if (Strings.isValid(data)) { |
| boolean wasCData = false; |
| NodeList childNodes = element.getChildNodes(); |
| for (int i = 0; i < childNodes.getLength(); i++) { |
| Node n = childNodes.item(i); |
| if (n.getNodeType() == Node.TEXT_NODE) { |
| wasCData = true; |
| break; |
| } |
| } |
| if (wasCData) { |
| writer.writeCharacters(data); |
| } else { |
| writer.writeCData(data); |
| } |
| } |
| writer.writeEndElement(); |
| } |
| } |
| } |
| |
| public static void serialize(XMLStreamWriter writer, NodeList nodes, boolean trimTextNodeWhitespace) throws XMLStreamException { |
| for (int index = 0; index < nodes.getLength(); index++) { |
| writeNode(writer, nodes.item(index), trimTextNodeWhitespace); |
| } |
| } |
| |
| public static void writeAttrNode(XMLStreamWriter writer, Node node) throws XMLStreamException { |
| if (node instanceof Attr) { |
| Attr attrNode = (Attr) node; |
| |
| String namespace = attrNode.getNamespaceURI(); |
| String prefix = attrNode.getPrefix(); |
| String value = attrNode.getValue(); |
| |
| String name = attrNode.getLocalName(); |
| if (!Strings.isValid(name)) { |
| name = attrNode.getNodeName(); |
| } |
| |
| if (Strings.isValid(name) && Strings.isValid(value)) { |
| if (prefix != null && namespace != null) { |
| writer.writeAttribute(prefix, namespace, name, value); |
| // } else if (namespace != null) { |
| // writer.writeAttribute(" ", namespace, name, value); |
| } else { |
| writer.writeAttribute(name, value); |
| } |
| } |
| } |
| } |
| } |