Skip to content

Commit

Permalink
Merge pull request #587 from dubinsky/parse-namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
SethTisue authored Feb 20, 2022
2 parents f931732 + 363ac31 commit 7c01069
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
29 changes: 29 additions & 0 deletions jvm/src/test/scala/scala/xml/XMLTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,35 @@ class XMLTestJVM {
// does not work: roundtripNodes("<a/> <!-- epilogue -->")
}

// 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, """<book xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"/>""")

@UnitTest
def namespaceAware: Unit =
roundtrip(namespaceAware = true, """<book xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"/>""")

@UnitTest
def namespaceAware2: Unit =
roundtrip(namespaceAware = true, """<book xmlns="http://docbook.org/ns/docbook" xmlns:xi="http://www.w3.org/2001/XInclude"><svg xmlns:svg="http://www.w3.org/2000/svg"/></book>""")

@UnitTest
def nodeSeqNs: Unit = {
val x = {
Expand Down
15 changes: 15 additions & 0 deletions shared/src/main/scala/scala/xml/parsing/FactoryAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down

0 comments on commit 7c01069

Please sign in to comment.