diff options
author | Tor Norbye <tnorbye@google.com> | 2012-12-07 15:08:53 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-12-07 15:08:53 -0800 |
commit | 69fa7f69b9a82e2c669dad67f71433e09fb44702 (patch) | |
tree | 2c34f2b9bacc8223b8948ab1cd7a80f48d3c341b /common | |
parent | a7ec962feba1e5e47b8e3494f215b8bc83b0ed0c (diff) | |
download | sdk-69fa7f69b9a82e2c669dad67f71433e09fb44702.zip sdk-69fa7f69b9a82e2c669dad67f71433e09fb44702.tar.gz sdk-69fa7f69b9a82e2c669dad67f71433e09fb44702.tar.bz2 |
Add simple XML dump method
Change-Id: I46709d9903e3f2daf4165e17f1e4b581cc217315
Diffstat (limited to 'common')
-rw-r--r-- | common/.settings/org.moreunit.prefs | 3 | ||||
-rw-r--r-- | common/src/main/java/com/android/utils/XmlUtils.java | 140 | ||||
-rw-r--r-- | common/src/test/.settings/org.moreunit.prefs | 4 | ||||
-rw-r--r-- | common/src/test/java/com/android/utils/XmlUtilsTest.java | 54 |
4 files changed, 198 insertions, 3 deletions
diff --git a/common/.settings/org.moreunit.prefs b/common/.settings/org.moreunit.prefs index c0ed4c1..3001cbf 100644 --- a/common/.settings/org.moreunit.prefs +++ b/common/.settings/org.moreunit.prefs @@ -1,5 +1,4 @@ -#Thu Jan 05 10:46:32 PST 2012 eclipse.preferences.version=1 org.moreunit.prefixes= -org.moreunit.unitsourcefolder=common\:src\:common-tests\:src +org.moreunit.unitsourcefolder=common\:src/main/java\:common-tests\:java org.moreunit.useprojectsettings=true diff --git a/common/src/main/java/com/android/utils/XmlUtils.java b/common/src/main/java/com/android/utils/XmlUtils.java index 0969eb1..c77baee 100644 --- a/common/src/main/java/com/android/utils/XmlUtils.java +++ b/common/src/main/java/com/android/utils/XmlUtils.java @@ -29,11 +29,14 @@ import static com.android.SdkConstants.XMLNS_URI; import com.android.SdkConstants; import com.android.annotations.NonNull; import com.android.annotations.Nullable; +import com.google.common.base.Splitter; 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 java.util.HashSet; @@ -275,4 +278,139 @@ public class XmlUtils { } } } -} + + /** + * Dump an XML tree to string. This isn't going to do a beautiful job pretty + * printing the XML; it's intended mostly for non-user editable files and + * for debugging. If true, preserve whitespace exactly as in the DOM + * document (typically used for a DOM which is already formatted), otherwise + * this method will insert some newlines here and there (for example, one + * per element and one per attribute.) + * + * @param node the node (which can be a document, an element, a text node, + * etc. + * @param preserveWhitespace whether to preserve the whitespace (text nodes) + * in the DOM + * @return a string version of the file + */ + public static String toXml(Node node, boolean preserveWhitespace) { + StringBuilder sb = new StringBuilder(1000); + + append(sb, node, 0, preserveWhitespace); + + return sb.toString(); + } + + private static void indent(StringBuilder sb, int indent) { + for (int i = 0; i < indent; i++) { + sb.append(" "); + } + } + + private static void append( + @NonNull StringBuilder sb, + @NonNull Node node, + int indent, + boolean preserveWhitespace) { + short nodeType = node.getNodeType(); + switch (nodeType) { + case Node.DOCUMENT_NODE: + case Node.DOCUMENT_FRAGMENT_NODE: { + sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$ + NodeList children = node.getChildNodes(); + for (int i = 0, n = children.getLength(); i < n; i++) { + append(sb, children.item(i), indent, preserveWhitespace); + } + break; + } + case Node.COMMENT_NODE: + case Node.TEXT_NODE: { + if (nodeType == Node.COMMENT_NODE) { + if (!preserveWhitespace) { + indent(sb, indent); + } + sb.append("<!--"); //$NON-NLS-1$ + if (!preserveWhitespace) { + sb.append('\n'); + } + } + String text = node.getNodeValue(); + if (!preserveWhitespace) { + text = text.trim(); + for (String line : Splitter.on('\n').split(text)) { + indent(sb, indent + 1); + sb.append(toXmlTextValue(line)); + sb.append('\n'); + } + } else { + sb.append(toXmlTextValue(text)); + } + if (nodeType == Node.COMMENT_NODE) { + if (!preserveWhitespace) { + indent(sb, indent); + } + sb.append("-->"); //$NON-NLS-1$ + if (!preserveWhitespace) { + sb.append('\n'); + } + } + break; + } + case Node.ELEMENT_NODE: { + if (!preserveWhitespace) { + indent(sb, indent); + } + sb.append('<'); + Element element = (Element) node; + sb.append(element.getTagName()); + + NamedNodeMap attributes = element.getAttributes(); + NodeList children = element.getChildNodes(); + int childCount = children.getLength(); + int attributeCount = attributes.getLength(); + + if (attributeCount > 0) { + for (int i = 0; i < attributeCount; i++) { + Node attribute = attributes.item(i); + sb.append(' '); + sb.append(attribute.getNodeName()); + sb.append('=').append('"'); + sb.append(toXmlAttributeValue(attribute.getNodeValue())); + sb.append('"'); + } + } + + if (childCount == 0) { + sb.append('/'); + } + sb.append('>'); + if (!preserveWhitespace) { + sb.append('\n'); + } + if (childCount > 0) { + for (int i = 0; i < childCount; i++) { + Node child = children.item(i); + append(sb, child, indent + 1, preserveWhitespace); + } + if (!preserveWhitespace) { + if (sb.charAt(sb.length() - 1) != '\n') { + sb.append('\n'); + } + indent(sb, indent); + } + sb.append('<').append('/'); + sb.append(element.getTagName()); + sb.append('>'); + if (!preserveWhitespace) { + sb.append('\n'); + } + } + break; + } + + default: + throw new UnsupportedOperationException( + "Unsupported node type " + nodeType + ": not yet implemented"); + } + } +}
\ No newline at end of file diff --git a/common/src/test/.settings/org.moreunit.prefs b/common/src/test/.settings/org.moreunit.prefs new file mode 100644 index 0000000..5c0456e --- /dev/null +++ b/common/src/test/.settings/org.moreunit.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.moreunit.prefixes= +org.moreunit.unitsourcefolder=common-tests\:java\:common\:src/main/java +org.moreunit.useprojectsettings=true diff --git a/common/src/test/java/com/android/utils/XmlUtilsTest.java b/common/src/test/java/com/android/utils/XmlUtilsTest.java index 0e9289b..edf0235 100644 --- a/common/src/test/java/com/android/utils/XmlUtilsTest.java +++ b/common/src/test/java/com/android/utils/XmlUtilsTest.java @@ -18,11 +18,13 @@ package com.android.utils; import static com.android.SdkConstants.XMLNS; import com.android.SdkConstants; +import com.android.annotations.Nullable; 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 javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -113,4 +115,56 @@ public class XmlUtilsTest extends TestCase { XmlUtils.appendXmlTextValue(sb, "<\"'>&"); assertEquals("<\"'>&", sb.toString()); } + + public void testNew() throws Exception { + Document doc = createEmptyPlainDocument(); + Element root = doc.createElement("myroot"); + doc.appendChild(root); + root.setAttribute("foo", "bar"); + root.setAttribute("baz", "baz"); + Element child = doc.createElement("mychild"); + root.appendChild(child); + Element child2 = doc.createElement("hasComment"); + root.appendChild(child2); + Node comment = doc.createComment("This is my comment"); + child2.appendChild(comment); + Element child3 = doc.createElement("hasText"); + root.appendChild(child3); + Node text = doc.createTextNode(" This is my text "); + child3.appendChild(text); + + String xml = XmlUtils.toXml(doc, false); + assertEquals( + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<myroot baz=\"baz\" foo=\"bar\">\n" + + " <mychild/>\n" + + " <hasComment>\n" + + " <!--\n" + + " This is my comment\n" + + " -->\n" + + " </hasComment>\n" + + " <hasText>\n" + + " This is my text\n" + + " </hasText>\n" + + "</myroot>\n", + xml); + + xml = XmlUtils.toXml(doc, true); + assertEquals( + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<myroot baz=\"baz\" foo=\"bar\"><mychild/><hasComment><!--This is my comment--></hasComment><hasText> This is my text </hasText></myroot>", + xml); + + } + + @Nullable + private static Document createEmptyPlainDocument() throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(false); + factory.setIgnoringComments(true); + DocumentBuilder builder; + builder = factory.newDocumentBuilder(); + return builder.newDocument(); + } } |