diff --git a/jvm/src/test/scala/scala/xml/XMLTest.scala b/jvm/src/test/scala/scala/xml/XMLTest.scala
index e7f3624f..3f6eb62e 100644
--- a/jvm/src/test/scala/scala/xml/XMLTest.scala
+++ b/jvm/src/test/scala/scala/xml/XMLTest.scala
@@ -629,6 +629,35 @@ class XMLTestJVM {
// does not work: roundtripNodes(" ")
}
+ // using non-namespace-aware parser, this always worked;
+ // using namespace-aware parser, this works with FactoryAdapter enhanced to handle startPrefixMapping() events;
+ // see https://github.com/scala/scala-xml/issues/506
+ def roundtrip(namespaceAware: Boolean, xml: String): Unit = {
+ val parserFactory: javax.xml.parsers.SAXParserFactory = javax.xml.parsers.SAXParserFactory.newInstance()
+ parserFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true)
+ parserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
+ parserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
+ parserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
+ parserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false)
+ parserFactory.setFeature("http://xml.org/sax/features/resolve-dtd-uris", false)
+ parserFactory.setNamespaceAware(namespaceAware)
+ parserFactory.setXIncludeAware(namespaceAware)
+
+ assertEquals(xml, XML.withSAXParser(parserFactory.newSAXParser()).loadString(xml).toString())
+ }
+
+ @UnitTest
+ def namespaceUnaware: Unit =
+ roundtrip(namespaceAware = false, """""")
+
+ @UnitTest
+ def namespaceAware: Unit =
+ roundtrip(namespaceAware = true, """""")
+
+ @UnitTest
+ def namespaceAware2: Unit =
+ roundtrip(namespaceAware = true, """""")
+
@UnitTest
def nodeSeqNs: Unit = {
val x = {
diff --git a/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala b/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala
index 18d32633..eaa43afd 100644
--- a/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala
+++ b/shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala
@@ -211,10 +211,25 @@ abstract class FactoryAdapter extends DefaultHandler2 with factory.XMLLoader[Nod
m = Attribute(Option(pre), key, Text(value), m)
}
+ // Add namespace bindings for the prefix mappings declared by this element
+ // (if there are any, the parser is namespace-aware, and no namespace bindings were delivered as attributes).
+ // All `startPrefixMapping()` events will occur immediately before the corresponding `startElement()` event.
+ for ((prefix: String, uri: String) <- prefixMappings)
+ scpe = NamespaceBinding(if (prefix.isEmpty) null else prefix, uri, scpe)
+
+ // Once the `prefixMappings` are processed into `scpe`, the list is emptied out
+ // so that already-declared namespaces are not re-declared on the nested elements.
+ prefixMappings = List.empty
+
scopeStack = scpe :: scopeStack
attribStack = m :: attribStack
}
+ private var prefixMappings: List[(String, String)] = List.empty
+
+ override def startPrefixMapping(prefix: String, uri: String): Unit =
+ prefixMappings = (prefix, uri) :: prefixMappings
+
/**
* Captures text or cdata.
*/