diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index f6df91214..dd98e7b80 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -217,8 +217,14 @@ public class PacketParserUtils { * @throws IOException */ public static String parseElement(XmlPullParser parser) throws XmlPullParserException, IOException { - assert(parser.getEventType() == XmlPullParser.START_TAG); - return parseContentDepth(parser, parser.getDepth()); + return parseElement(parser, false); + } + + public static String parseElement(XmlPullParser parser, + boolean fullNamespaces) throws XmlPullParserException, + IOException { + assert (parser.getEventType() == XmlPullParser.START_TAG); + return parseContentDepth(parser, parser.getDepth(), fullNamespaces); } /** @@ -245,28 +251,36 @@ public class PacketParserUtils { } // Advance the parser, since we want to parse the content of the current element parser.next(); - return parseContentDepth(parser, parser.getDepth()); + return parseContentDepth(parser, parser.getDepth(), false); + } + + public static String parseContentDepth(XmlPullParser parser, int depth) + throws XmlPullParserException, IOException { + return parseContentDepth(parser, depth, false); } /** * Returns the content from the current position of the parser up to the closing tag of the * given depth. Note that only the outermost namespace attributes ("xmlns") will be returned, - * not nested ones. + * not nested ones, if fullNamespaces is false. If it is true, then namespaces of + * parent elements will be added to child elements that don't define a different namespace. *

* This method is able to parse the content with MX- and KXmlParser. In order to achieve * this some trade-off has to be make, because KXmlParser does not support xml-roundtrip (ie. * return a String on getText() on START_TAG and END_TAG). We are therefore required to work * around this limitation, which results in only partial support for XML namespaces ("xmlns"): - * Only the outermost namespace of elements will be included in the resulting String. + * Only the outermost namespace of elements will be included in the resulting String, if + * fullNamespaces is set to false. *

* * @param parser * @param depth + * @param fullNamespaces * @return the content of the current depth * @throws XmlPullParserException * @throws IOException */ - public static String parseContentDepth(XmlPullParser parser, int depth) throws XmlPullParserException, IOException { + public static String parseContentDepth(XmlPullParser parser, int depth, boolean fullNamespaces) throws XmlPullParserException, IOException { XmlStringBuilder xml = new XmlStringBuilder(); int event = parser.getEventType(); boolean isEmptyElement = false; @@ -277,7 +291,7 @@ public class PacketParserUtils { while (true) { if (event == XmlPullParser.START_TAG) { xml.halfOpenElement(parser.getName()); - if (namespaceElement == null) { + if (namespaceElement == null || fullNamespaces) { String namespace = parser.getNamespace(); if (StringUtils.isNotEmpty(namespace)) { xml.attribute("xmlns", namespace); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java b/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java index ebf801c23..a78412280 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java @@ -67,7 +67,7 @@ public class ParsingExceptionTest { try { PacketParserUtils.parseMessage(parser); } catch (Exception e) { - content = PacketParserUtils.parseContentDepth(parser, parserDepth); + content = PacketParserUtils.parseContentDepth(parser, parserDepth, false); } assertNotNull(content); assertEquals(MESSAGE_EXCEPTION_ELEMENT + EXTENSION2 + "", content); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java b/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java index 39e484ee2..95db3aa2a 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java @@ -24,9 +24,14 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.IOException; import java.util.Locale; import java.util.Properties; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier; import org.jivesoftware.smack.packet.Message; @@ -34,6 +39,7 @@ import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.test.util.TestUtils; import org.junit.Test; +import org.xml.sax.SAXException; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -790,6 +796,23 @@ public class PacketParserUtilsTest { assertEquals("", content); } + @Test + public void parseElementMultipleNamespace() + throws ParserConfigurationException, + FactoryConfigurationError, XmlPullParserException, + IOException, TransformerException, SAXException { + // @formatter:off + final String stanza = XMLBuilder.create("outer", "outerNamespace").a("outerAttribute", "outerValue") + .element("inner", "innerNamespace").a("innverAttribute", "innerValue") + .element("innermost") + .t("some text") + .asString(); + // @formatter:on + XmlPullParser parser = TestUtils.getParser(stanza, "outer"); + String result = PacketParserUtils.parseElement(parser, true); + assertXMLEqual(stanza, result); + } + private String determineNonDefaultLanguage() { String otherLanguage = "jp"; Locale[] availableLocales = Locale.getAvailableLocales(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java index 3dc3b1cb7..530863269 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java @@ -54,7 +54,7 @@ public class ItemProvider implements PacketExtensionProvider if (ProviderManager.getExtensionProvider(payloadElemName, payloadNS) == null) { - String payloadText = PacketParserUtils.parseElement(parser); + String payloadText = PacketParserUtils.parseElement(parser, true); return new PayloadItem(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText)); } else