From 3395b0baa9e85934a0389bc9dc576a1c62026e75 Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 15 Feb 2009 09:32:12 +0000 Subject: [PATCH] Silk -> XML git-svn-id: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core@2976 ae02f08e-27ec-0310-ae8c-8ba02fe2eafd --- src/main/java/org/xerial/json/JSONWriter.java | 46 ++--- src/main/java/org/xerial/silk/SilkUtil.java | 220 +++++++++++++++++++++ src/main/java/org/xerial/silk/SilkWalker.java | 179 +++++++++++++---- .../java/org/xerial/util/xml/XMLAttribute.java | 13 +- .../java/org/xerial/util/xml/XMLGenerator.java | 11 +- src/test/java/org/xerial/silk/SilkUtilTest.java | 68 +++++++ 6 files changed, 472 insertions(+), 65 deletions(-) create mode 100644 src/main/java/org/xerial/silk/SilkUtil.java create mode 100644 src/test/java/org/xerial/silk/SilkUtilTest.java diff --git a/src/main/java/org/xerial/json/JSONWriter.java b/src/main/java/org/xerial/json/JSONWriter.java index 1b3ec90..ac6acf1 100644 --- a/src/main/java/org/xerial/json/JSONWriter.java +++ b/src/main/java/org/xerial/json/JSONWriter.java @@ -25,6 +25,7 @@ package org.xerial.json; import java.io.IOException; +import java.io.PrintWriter; import java.io.Reader; import java.io.Writer; import java.util.LinkedList; @@ -42,7 +43,7 @@ import org.xerial.util.bean.BeanUtil; */ public class JSONWriter { - private final Writer writer; + private final PrintWriter writer; enum JSONState { InObject, InArray, InString, Root, Unknown @@ -53,7 +54,7 @@ public class JSONWriter public JSONWriter(Writer writer) { - this.writer = writer; + this.writer = new PrintWriter(writer); stateStack.add(JSONState.Root); elementCountStack.add(0); } @@ -89,41 +90,41 @@ public class JSONWriter elementCountStack.add(++count); } - public void startObject() throws IOException + public void startObject() { if (getCurrentState() == JSONState.InArray) putComma(); - writer.append("{"); + writer.print("{"); pushState(JSONState.InObject); } - public void endObject() throws IOException + public void endObject() { if (getCurrentState() != JSONState.InObject) throw new XerialError(JSONErrorCode.NotInAJSONObject, "cannot end the object outside of the JSON object"); - writer.append("}"); + writer.print("}"); popState(); if (getCurrentState() == JSONState.InArray) incrementElementCount(); } - public void startArray() throws IOException + public void startArray() { - writer.append("["); + writer.print("["); pushState(JSONState.InArray); } - public void endArray() throws IOException + public void endArray() { if (getCurrentState() != JSONState.InArray) throw new XerialError(JSONErrorCode.NotInAJSONArray, "cannot end the arry outside of the JSON array"); - writer.append("]"); + writer.print("]"); popState(); } - public void startString() throws IOException + public void startString() { if (getCurrentState() == JSONState.InArray) throw new XerialError(JSONErrorCode.NotInAJSONArray, @@ -133,14 +134,14 @@ public class JSONWriter pushState(JSONState.InString); } - public void startString(String key) throws IOException + public void startString(String key) { outputKeyPart(key); writer.append("\""); pushState(JSONState.InString); } - public void append(String stringFragment) throws IOException + public void append(String stringFragment) { if (getCurrentState() != JSONState.InString) throw new XerialError(JSONErrorCode.NotInAJSONString, @@ -158,16 +159,16 @@ public class JSONWriter popState(); } - public void startArray(String key) throws IOException + public void startArray(String key) { if (getCurrentState() != JSONState.InObject) throw new XerialError(JSONErrorCode.NotInAJSONObject, "cannot start a keyed array outside of the JSON object"); if (getPreviousElementCount() > 0) - writer.append(","); - writer.append(doubleQuote(key)); - writer.append(":["); + writer.print(","); + writer.print(doubleQuote(key)); + writer.print(":["); incrementElementCount(); pushState(JSONState.InArray); } @@ -233,10 +234,10 @@ public class JSONWriter incrementElementCount(); } - private void putComma() throws IOException + private void putComma() { if (getPreviousElementCount() > 0) - writer.append(","); + writer.print(","); } public void put(String key, String value) throws IOException @@ -283,6 +284,7 @@ public class JSONWriter * @param key * @param input * @throws IOException + * @throws IOException */ public void putString(String key, Reader input) throws IOException { @@ -302,7 +304,7 @@ public class JSONWriter incrementElementCount(); } - private void outputKeyPart(String key) throws IOException + private void outputKeyPart(String key) { if (getCurrentState() != JSONState.InObject) throw new XerialError(JSONErrorCode.NotInAJSONObject, @@ -313,12 +315,12 @@ public class JSONWriter writer.append(":"); } - public void flush() throws IOException + public void flush() { writer.flush(); } - public void endJSON() throws IOException + public void endJSON() { for (ListIterator it = stateStack.listIterator(stateStack.size()); it.hasPrevious();) { diff --git a/src/main/java/org/xerial/silk/SilkUtil.java b/src/main/java/org/xerial/silk/SilkUtil.java new file mode 100644 index 0000000..df4bf64 --- /dev/null +++ b/src/main/java/org/xerial/silk/SilkUtil.java @@ -0,0 +1,220 @@ +/*-------------------------------------------------------------------------- + * Copyright 2009 Taro L. Saito + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *--------------------------------------------------------------------------*/ +//-------------------------------------- +// XerialJ +// +// SilkUtil.java +// Since: 2009/02/13 21:15:32 +// +// $URL$ +// $Author$ +//-------------------------------------- +package org.xerial.silk; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URL; +import java.util.ArrayDeque; +import java.util.Deque; + +import org.xerial.core.XerialError; +import org.xerial.core.XerialException; +import org.xerial.json.JSONWriter; +import org.xerial.util.tree.TreeEvent; +import org.xerial.util.tree.TreeVisitor; +import org.xerial.util.tree.TreeVisitorBase; +import org.xerial.util.tree.TreeWalker; +import org.xerial.util.xml.XMLAttribute; +import org.xerial.util.xml.XMLErrorCode; +import org.xerial.util.xml.XMLGenerator; + +/** + * Utilities for handling Silk file format. + * + * @author leo + * + */ +public class SilkUtil +{ + public static String toXML(URL silkSource) throws IOException, XerialException + { + StringWriter buf = new StringWriter(); + toXML(silkSource, buf); + return buf.toString(); + } + + /** + * Convert the silk file into XML + * + * @param silkSource + * @param out + * @throws IOException + * @throws XerialException + */ + public static void toXML(URL silkSource, Writer out) throws IOException, XerialException + { + SilkWalker walker = new SilkWalker(silkSource); + XMLBuilder builder = new XMLBuilder(out); + walker.walk(builder); + + } + + /** + * + *
+     * 1:visit -> 2:visit : pop(1), startTag(1, value=".."), push(2:visit)
+     * 1:visit -> 2:text : pop(1), startTag(1, value=".."), text(2:text) 
+     * 1:visit -> 2:leave : pop(1), selfCloseTag(1, value="..")
+     * 
+ * + * @author leo + * + */ + private static class XMLBuilder extends TreeVisitorBase + { + final XMLGenerator xout; + final Deque eventQueue = new ArrayDeque(); + + public XMLBuilder(Writer out) + { + xout = new XMLGenerator(out); + } + + private void popQueue() + { + if (!eventQueue.isEmpty()) + { + TreeEvent prev = eventQueue.removeLast(); + + switch (prev.event) + { + case VISIT: + if (prev.nodeValue == null) + xout.startTag(prev.nodeName); + else + xout.startTag(prev.nodeName, new XMLAttribute("value", prev.nodeValue)); + break; + default: + throw new XerialError(XMLErrorCode.INVALID_XML_STRUCTURE); + } + } + + } + + @Override + public void visitNode(String nodeName, String immediateNodeValue, TreeWalker walker) throws XerialException + { + popQueue(); + eventQueue.addLast(new TreeEvent(TreeEvent.EventType.VISIT, nodeName, immediateNodeValue)); + } + + @Override + public void text(String textDataFragment, TreeWalker walker) throws XerialException + { + popQueue(); + xout.text(textDataFragment); + } + + @Override + public void leaveNode(String nodeName, TreeWalker walker) throws XerialException + { + if (!eventQueue.isEmpty()) + { + TreeEvent prev = eventQueue.removeLast(); + + switch (prev.event) + { + case VISIT: + if (prev.nodeValue == null) + xout.selfCloseTag(prev.nodeName); + else + xout.element(prev.nodeName, prev.nodeValue); + } + } + else + xout.endTag(); + } + + @Override + public void init(TreeWalker walker) throws XerialException + { + visitNode("silk", null, walker); + } + + @Override + public void finish(TreeWalker walker) throws XerialException + { + leaveNode("silk", walker); + xout.endDocument(); + } + } + + public static void toJSON(URL silkSource, Writer out) throws IOException, XerialException + { + SilkWalker walker = new SilkWalker(silkSource); + JSONBuilder builder = new JSONBuilder(out); + walker.walk(builder); + } + + private static class JSONBuilder implements TreeVisitor + { + final JSONWriter jout; + + public JSONBuilder(Writer out) + { + jout = new JSONWriter(out); + } + + public void finish(TreeWalker walker) throws XerialException + { + jout.endArray(); + + } + + public void init(TreeWalker walker) throws XerialException + { + jout.startArray(); + + } + + public void leaveNode(String nodeName, TreeWalker walker) throws XerialException + { + // TODO Auto-generated method stub + + } + + public void text(String textDataFragment, TreeWalker walker) throws XerialException + { + // TODO Auto-generated method stub + + } + + public void visitNode(String nodeName, String immediateNodeValue, TreeWalker walker) throws XerialException + { + // TODO Auto-generated method stub + + } + + } + + /** + * Forbid construction + */ + protected SilkUtil() + {} + +} diff --git a/src/main/java/org/xerial/silk/SilkWalker.java b/src/main/java/org/xerial/silk/SilkWalker.java index eff17f5..56e69c6 100644 --- a/src/main/java/org/xerial/silk/SilkWalker.java +++ b/src/main/java/org/xerial/silk/SilkWalker.java @@ -39,6 +39,8 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.xerial.core.XerialError; +import org.xerial.core.XerialErrorCode; import org.xerial.core.XerialException; import org.xerial.json.JSONArray; import org.xerial.json.JSONException; @@ -70,10 +72,6 @@ import org.xerial.util.tree.TreeWalker; /** * {@link TreeWalker} implementation of the Silk format. * - *
- * @
- * 
- * * @author leo * */ @@ -149,7 +147,7 @@ public class SilkWalker implements TreeWalker * @param input * `@throws IOException */ - public SilkWalker(InputStream input) throws IOException + protected SilkWalker(InputStream input) throws IOException { this.parser = new SilkPullParser(input); init(); @@ -161,7 +159,7 @@ public class SilkWalker implements TreeWalker * @param input * @throws IOException */ - public SilkWalker(Reader input) throws IOException + protected SilkWalker(Reader input) throws IOException { this.parser = new SilkPullParser(input); init(); @@ -178,12 +176,12 @@ public class SilkWalker implements TreeWalker init(); } - public SilkWalker(URL resource) throws IOException + public SilkWalker(URL resourcePath) throws IOException { - String path = resource.toExternalForm(); + String path = resourcePath.toExternalForm(); int fileNamePos = path.lastIndexOf("/"); this.resourceBasePath = fileNamePos > 0 ? path.substring(0, fileNamePos) : null; - this.parser = new SilkPullParser(new BufferedReader(new InputStreamReader(resource.openStream()))); + this.parser = new SilkPullParser(new BufferedReader(new InputStreamReader(resourcePath.openStream()))); init(); } @@ -311,7 +309,7 @@ public class SilkWalker implements TreeWalker { while (!builder.hasFinished()) { - step(); + stepNext(); } } finally @@ -322,6 +320,10 @@ public class SilkWalker implements TreeWalker return builder.getSubtreeRoot(); } + /** + * If this stack is not empty, we must disable event reporting to the + * {@link TreeVisitor} + */ private ArrayDeque skipNodeStack = new ArrayDeque(); public void skipDescendants() @@ -332,23 +334,48 @@ public class SilkWalker implements TreeWalker skipNodeStack.addLast(currentEvent.nodeName); } + /** + * Enqueues a visit event. + * + * @param nodeName + * @param immediateNodeValue + * @throws XerialException + */ private void visit(String nodeName, String immediateNodeValue) throws XerialException { eventQueue.addLast(new TreeEvent(TreeEvent.EventType.VISIT, nodeName, immediateNodeValue)); } + /** + * Enqueues a leave event + * + * @param nodeName + * @throws XerialException + */ private void leave(String nodeName) throws XerialException { eventQueue.addLast(new TreeEvent(TreeEvent.EventType.LEAVE, nodeName, null)); } + /** + * Enqueues a text event + * + * @param textFragment + * @throws XerialException + */ private void text(String textFragment) throws XerialException { eventQueue.addLast(new TreeEvent(TreeEvent.EventType.TEXT, null, textFragment)); } - private void closeUpTo(int newIndentLevel) throws XerialException + /** + * Closed pre-opened contexts up to the specified indent level + * + * @param newIndentLevel + * @throws XerialException + */ + private void closeContextUpTo(int newIndentLevel) throws XerialException { // if (newIndentLevel == SilkNode.NO_INDENT) // newIndentLevel = contextNodeStack.isEmpty() ? 0 : contextNodeStack.peekLast().getIndentLevel() + 1; @@ -362,26 +389,32 @@ public class SilkWalker implements TreeWalker //outputDataCountStack.removeLast(); if (node.getOccurrence() != SilkNodeOccurrence.TABBED_SEQUENCE) - closeContext(node); + { + // close context + String nodeName = node.getName(); + leave(nodeName); + } } else return; } } - private void closeContext(SilkNode node) throws XerialException - { - String nodeName = node.getName(); - leave(nodeName); - } - - private void openContext(SilkNode node, TreeVisitor visitor) throws XerialException + /** + * Opens a new context for the given node + * + * @param node + * new context node + * @param visitor + * @throws XerialException + */ + private void openContext(SilkNode node) throws XerialException { int indentLevel = node.getIndentLevel(); if (indentLevel != SilkNode.NO_INDENT) indentLevel += indentationOffset; - closeUpTo(indentLevel); + closeContextUpTo(indentLevel); contextNodeStack.addLast(node); //outputDataCountStack.addLast(0); @@ -393,8 +426,10 @@ public class SilkWalker implements TreeWalker SilkValue textValue = node.getValue(); + // process text values attached to the node if (textValue != null) { + // When the text data is JSON, traverses the JSON data if (textValue.isJSON()) { visit(nodeName, null); @@ -412,30 +447,44 @@ public class SilkWalker implements TreeWalker } else if (textValue.isFunction()) { + // evaluate the function visit(nodeName, null); SilkFunction function = SilkFunction.class.cast(textValue); - evalFunction(function, visitor); + evalFunction(function); return; } else + { + // Simple text value will be reported as it is. visit(nodeName, textValue.toString()); + } } else + { + // Report a visit event without text value visit(nodeName, null); + } - // traverse attribute nodes with text values + // Traverse attribute nodes which have text values. If no text value is specified for an attribute, + // this attribute is a schema element for the following DATA_LINE for (SilkNode eachChild : node.getChildNodes()) { if (eachChild.hasValue()) { - openContext(eachChild, visitor); + openContext(eachChild); } } } - private void evalFunction(SilkFunction function, TreeVisitor visitor) throws XerialException + /** + * Evaluate the function + * + * @param function + * @throws XerialException + */ + private void evalFunction(SilkFunction function) throws XerialException { if (!skipNodeStack.isEmpty()) return; // skip evaluation @@ -446,6 +495,7 @@ public class SilkWalker implements TreeWalker _logger.error(String.format("plugin %s not found", function.getName())); return; } + // fill the function argument to the plugin instance populate(plugin, function.getArgumentList()); plugin.eval(new SilkEnvImpl(function, visitor)); @@ -468,14 +518,19 @@ public class SilkWalker implements TreeWalker while (hasNext()) { - step(); + stepNext(); } } - private void step() throws XerialException + /** + * Consume the next event, and call its corresponding visitor event. + * + * @throws XerialException + */ + private void stepNext() throws XerialException { - currentEvent = next(); + currentEvent = getNextEvent(); //_logger.info("step: " + currentEvent); switch (currentEvent.event) @@ -517,8 +572,17 @@ public class SilkWalker implements TreeWalker } + /** + * Has finished reading the stream? + */ private boolean hasFinished = false; + /** + * Is next event available? + * + * @return true if there are remaining events, otherwise fales + * @throws XerialException + */ private boolean hasNext() throws XerialException { if (eventQueue.isEmpty()) @@ -533,23 +597,37 @@ public class SilkWalker implements TreeWalker return true; } - private TreeEvent next() throws XerialException + /** + * Retrieves the next event from the queue. If the event queue is empty, + * fill the queue with the next event + * + * @return the next event. + * @throws XerialException + */ + private TreeEvent getNextEvent() throws XerialException { if (!eventQueue.isEmpty()) return eventQueue.removeFirst(); if (hasFinished) - return null; + throw new XerialError(XerialErrorCode.INVALID_STATE, + "hasNext() value must be checked before calling getNextEvent()"); fillQueue(); - return next(); + return getNextEvent(); } + /** + * Fill the queue by retrieving the next event from the pull parser. + * + * @throws XerialException + */ private void fillQueue() throws XerialException { if (!parser.hasNext()) { - closeUpTo(indentationOffset); + // no more input data + closeContextUpTo(indentationOffset); hasFinished = true; return; } @@ -567,15 +645,15 @@ public class SilkWalker implements TreeWalker case NODE: // push context node SilkNode newContextNode = SilkNode.class.cast(currentEvent.getElement()); - openContext(newContextNode, visitor); + openContext(newContextNode); break; case FUNCTION: SilkFunction function = SilkFunction.class.cast(currentEvent.getElement()); - evalFunction(function, visitor); + evalFunction(function); break; case DATA_LINE: - // pop the context stack up to the node with stream data node occurrence + // pop the context stack until finding a node for stream data node occurrence while (!contextNodeStack.isEmpty()) { SilkNode node = contextNodeStack.peekLast(); @@ -729,8 +807,18 @@ public class SilkWalker implements TreeWalker } + /** + * Plugin holder + */ private static Map> pluginTable = null; + /** + * Get the plugin of the specified name + * + * @param name + * plugin name + * @return plugin instance or null if no corresponding plugin is found. + */ private SilkFunctionPlugin getPlugin(String name) { Class pluginClass = getPluginTable().get(name); @@ -772,6 +860,14 @@ public class SilkWalker implements TreeWalker return pluginTable; } + /** + * Information of the function (plugin) arguments ( + * {@link SilkFunctionArgument}) described in the Class definition, which + * implements {@link SilkFunctionPlugin}. + * + * @author leo + * + */ private static class PluginField { Field field; @@ -871,12 +967,25 @@ public class SilkWalker implements TreeWalker } - private void populate(SilkFunctionPlugin plugin, List args) + /** + * Fill the plug-in argument fields with the given arguments + * + * @param plugin + * plug-in instance. + * @param args + * function arguments. + */ + private static void populate(SilkFunctionPlugin plugin, List args) { PluginHolder holder = new PluginHolder(plugin.getClass()); holder.populate(plugin, args); } + /** + * Get the context node + * + * @return + */ private SilkNode getContextNode() { if (contextNodeStack.isEmpty()) diff --git a/src/main/java/org/xerial/util/xml/XMLAttribute.java b/src/main/java/org/xerial/util/xml/XMLAttribute.java index 1d6501a..3a62a4d 100644 --- a/src/main/java/org/xerial/util/xml/XMLAttribute.java +++ b/src/main/java/org/xerial/util/xml/XMLAttribute.java @@ -79,8 +79,9 @@ public class XMLAttribute public XMLAttribute add(String attributeName, String attributeValue) { - _attributeNameList.add(attributeName); - _attributeValue.put(attributeName, attributeValue); + String name = XMLGenerator.replaceWhiteSpaces(attributeName); + _attributeNameList.add(name); + _attributeValue.put(name, attributeValue); return this; } @@ -119,7 +120,7 @@ public class XMLAttribute Set< ? > keySet = properties.keySet(); for (Object attributeObj : keySet) { - String attribute = attributeObj.toString(); + String attribute = XMLGenerator.replaceWhiteSpaces(attributeObj.toString()); String value = properties.getProperty(attribute); this.add(attribute, value); } @@ -130,7 +131,7 @@ public class XMLAttribute Set< ? > keySet = properties.keySet(); for (Object attributeObj : keySet) { - String attribute = attributeObj.toString(); + String attribute = XMLGenerator.replaceWhiteSpaces(attributeObj.toString()); String value = properties.get(attribute).toString(); this.add(attribute, value); } @@ -181,6 +182,6 @@ public class XMLAttribute return returnString; } - protected LinkedList _attributeNameList = new LinkedList(); - protected HashMap _attributeValue = new HashMap(); + protected LinkedList _attributeNameList = new LinkedList(); + protected HashMap _attributeValue = new HashMap(); } diff --git a/src/main/java/org/xerial/util/xml/XMLGenerator.java b/src/main/java/org/xerial/util/xml/XMLGenerator.java index 9e5f867..2fc754d 100644 --- a/src/main/java/org/xerial/util/xml/XMLGenerator.java +++ b/src/main/java/org/xerial/util/xml/XMLGenerator.java @@ -107,12 +107,19 @@ public class XMLGenerator } } + public static String replaceWhiteSpaces(String tagName) + { + return tagName.replaceAll("\\s+", "_"); + } + public XMLGenerator startTag(String tagName, XMLAttribute attribute) { beforeStartTag(); + String tag = replaceWhiteSpaces(tagName); + _out.print("<"); - _out.print(tagName); + _out.print(tag); if (attribute != null && attribute.length() > 0) { @@ -122,7 +129,7 @@ public class XMLGenerator _out.print(">"); _currentLevel++; - _tagStack.add(tagName); + _tagStack.add(tag); _prevOut = PreviousOutput.StartTag; return this; diff --git a/src/test/java/org/xerial/silk/SilkUtilTest.java b/src/test/java/org/xerial/silk/SilkUtilTest.java new file mode 100644 index 0000000..7f97364 --- /dev/null +++ b/src/test/java/org/xerial/silk/SilkUtilTest.java @@ -0,0 +1,68 @@ +/*-------------------------------------------------------------------------- + * Copyright 2009 Taro L. Saito + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *--------------------------------------------------------------------------*/ +//-------------------------------------- +// XerialJ +// +// SilkUtilTest.java +// Since: 2009/02/14 5:57:08 +// +// $URL$ +// $Author$ +//-------------------------------------- +package org.xerial.silk; + +import java.io.IOException; +import java.io.StringReader; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.xerial.core.XerialException; +import org.xerial.util.FileResource; +import org.xerial.util.log.Logger; +import org.xerial.util.xml.pullparser.PullParserUtil; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +public class SilkUtilTest +{ + private static Logger _logger = Logger.getLogger(SilkUtilTest.class); + + @Before + public void setUp() throws Exception + {} + + @After + public void tearDown() throws Exception + {} + + @Test + public void testToXML() throws IOException, XerialException, XmlPullParserException + { + String xml = SilkUtil.toXML(FileResource.find(SilkUtilTest.class, "small.silk")); + _logger.info(xml); + + XmlPullParser pullParser = PullParserUtil.newParser(new StringReader(xml)); + + int event; + while ((event = pullParser.next()) != XmlPullParser.END_DOCUMENT) + { + + } + + } + +} -- 2.11.0