Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 0ff5588

Browse files
Merge pull request #659 from dubinsky/retain-systemId
Retain SystemId
2 parents 42a59a8 + aac142a commit 0ff5588

File tree

3 files changed

+69
-61
lines changed

3 files changed

+69
-61
lines changed

‎jvm/src/test/scala/scala/xml/XMLTest.scala‎

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ class XMLTestJVM {
2424
def Elem(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*): Elem =
2525
scala.xml.Elem.apply(prefix, label, attributes, scope, minimizeEmpty = true, child: _*)
2626

27-
lazy val parsedxml1: Elem = XML.load(newInputSource(newStringReader("<hello><world/></hello>")))
28-
lazy val parsedxml11: Elem = XML.load(newInputSource(newStringReader("<hello><world/></hello>")))
27+
lazy val parsedxml1: Elem = XML.loadString("<hello><world/></hello>")
28+
lazy val parsedxml11: Elem = XML.loadString("<hello><world/></hello>")
2929
val xmlFile2: String = "<bib><book><author>Peter Buneman</author><author>Dan Suciu</author><title>Data on ze web</title></book><book><author>John Mitchell</author><title>Foundations of Programming Languages</title></book></bib>"
30-
lazy val parsedxml2: Elem = XML.load(newInputSource(newStringReader(xmlFile2)))
30+
lazy val parsedxml2: Elem = XML.loadString(xmlFile2)
3131

3232
@UnitTest
3333
def equality(): Unit = {
@@ -46,9 +46,7 @@ class XMLTestJVM {
4646
assertTrue(Array(parsedxml1).toList sameElements List(parsedxml11))
4747

4848
val x2: String = "<book><author>Peter Buneman</author><author>Dan Suciu</author><title>Data on ze web</title></book>"
49-
50-
val i: InputSource = new InputSource(new StringReader(x2))
51-
val x2p: Elem = XML.load(i)
49+
val x2p: Elem = XML.loadString(x2)
5250

5351
assertEquals(Elem(null, "book", e, sc,
5452
Elem(null, "author", e, sc, Text("Peter Buneman")),
@@ -146,8 +144,7 @@ class XMLTestJVM {
146144
val xmlAttrValueNorm: String = "<personne id='p0003' nom='&#x015e;ahingšz' />"
147145

148146
{
149-
val isrcA: InputSource = new InputSource(new StringReader(xmlAttrValueNorm))
150-
val parsedxmlA: Elem = XML.load(isrcA)
147+
val parsedxmlA: Elem = XML.loadString(xmlAttrValueNorm)
151148
val c: Char = (parsedxmlA \ "@nom").text.charAt(0)
152149
assertTrue(c == '\u015e')
153150
}
@@ -689,6 +686,17 @@ class XMLTestJVM {
689686
assertTrue(gotAnError)
690687
}
691688

689+
// Here we see that opening InputStream prematurely, as was done previously, breaks XInclude.
690+
@UnitTest(expected = classOf[org.xml.sax.SAXParseException]) def xIncludeNeedsSystemId(): Unit = {
691+
val parserFactory = xercesInternal
692+
parserFactory.setNamespaceAware(true)
693+
parserFactory.setXIncludeAware(true)
694+
XML
695+
.withSAXParser(parserFactory.newSAXParser)
696+
.load(getClass.getResource("site.xml").openStream())
697+
.toString
698+
}
699+
692700
// Now that we can use XML parser configured to be namespace-aware,
693701
// we can also configure it to be XInclude-aware and process XML Includes:
694702
def check(
@@ -700,7 +708,7 @@ class XMLTestJVM {
700708
parserFactory.setXIncludeAware(true)
701709
val actual: String = XML
702710
.withSAXParser(parserFactory.newSAXParser)
703-
.load(getClass.getResource(resourceName).toString)
711+
.load(getClass.getResource(resourceName))
704712
.toString
705713

706714
assertEquals(expected, actual)

‎shared/src/main/scala/scala/xml/XML.scala‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ import java.nio.channels.Channels
1919
import scala.util.control.Exception.ultimately
2020

2121
object Source {
22-
def fromFile(file: File): InputSource = new InputSource(new FileInputStream(file))
23-
def fromFile(fd: FileDescriptor): InputSource = new InputSource(new FileInputStream(fd))
24-
def fromFile(name: String): InputSource = new InputSource(new FileInputStream(name))
25-
22+
def fromFile(name: String): InputSource = fromFile(new File(name))
23+
def fromFile(file: File): InputSource = fromUrl(file.toURI.toURL)
24+
def fromUrl(url: java.net.URL): InputSource = fromSysId(url.toString)
25+
def fromSysId(sysID: String): InputSource = new InputSource(sysID)
26+
def fromFile(fd: FileDescriptor): InputSource = fromInputStream(new FileInputStream(fd))
2627
def fromInputStream(is: InputStream): InputSource = new InputSource(is)
2728
def fromReader(reader: Reader): InputSource = new InputSource(reader)
28-
def fromSysId(sysID: String): InputSource = new InputSource(sysID)
2929
def fromString(string: String): InputSource = fromReader(new StringReader(string))
3030
}
3131

‎shared/src/main/scala/scala/xml/factory/XMLLoader.scala‎

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,36 @@ package scala
1414
package xml
1515
package factory
1616

17-
import org.xml.sax.{SAXNotRecognizedException, XMLReader}
17+
import org.xml.sax.{SAXNotRecognizedException, SAXNotSupportedException, XMLReader}
1818
import javax.xml.parsers.SAXParserFactory
1919
import parsing.{FactoryAdapter, NoBindingFactoryAdapter}
2020
import java.io.{File, FileDescriptor, InputStream, Reader}
2121
import java.net.URL
2222

2323
/**
2424
* Presents collection of XML loading methods which use the parser
25-
* created by "def parser".
25+
* created by "def parser" or the reader created by "def reader".
2626
*/
2727
trait XMLLoader[T <: Node] {
2828
import scala.xml.Source._
2929
def adapter: FactoryAdapter = new NoBindingFactoryAdapter()
3030

31+
private def setSafeDefaults(parserFactory: SAXParserFactory): Unit = {
32+
parserFactory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true)
33+
parserFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
34+
parserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
35+
parserFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
36+
parserFactory.setFeature("http://xml.org/sax/features/external-general-entities", false)
37+
parserFactory.setFeature("http://xml.org/sax/features/resolve-dtd-uris", false)
38+
parserFactory.setXIncludeAware(false)
39+
parserFactory.setNamespaceAware(false)
40+
}
41+
3142
private lazy val parserInstance: ThreadLocal[SAXParser] = new ThreadLocal[SAXParser] {
3243
override def initialValue: SAXParser = {
33-
val parser: SAXParserFactory = SAXParserFactory.newInstance
34-
parser.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true)
35-
parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
36-
parser.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true)
37-
parser.setFeature("http://xml.org/sax/features/external-parameter-entities", false)
38-
parser.setFeature("http://xml.org/sax/features/external-general-entities", false)
39-
parser.setFeature("http://xml.org/sax/features/resolve-dtd-uris", false)
40-
parser.setXIncludeAware(false)
41-
parser.setNamespaceAware(false)
42-
parser.newSAXParser
44+
val parserFactory: SAXParserFactory = SAXParserFactory.newInstance
45+
setSafeDefaults(parserFactory)
46+
parserFactory.newSAXParser
4347
}
4448
}
4549

@@ -51,72 +55,68 @@ trait XMLLoader[T <: Node] {
5155

5256
/**
5357
* Loads XML from the given InputSource, using the supplied parser.
54-
* The methods available in scala.xml.XML use the XML parser in the JDK.
58+
* The methods available in scala.xml.XML use the XML parser in the JDK
59+
* (unless another parser is present on the classpath).
5560
*/
56-
def loadXML(source: InputSource, parser: SAXParser): T = loadXML(source, parser.getXMLReader)
61+
def loadXML(inputSource: InputSource, parser: SAXParser): T = loadXML(inputSource, parser.getXMLReader)
5762

58-
def loadXMLNodes(source: InputSource, parser: SAXParser): Seq[Node] = loadXMLNodes(source, parser.getXMLReader)
63+
def loadXMLNodes(inputSource: InputSource, parser: SAXParser): Seq[Node] = loadXMLNodes(inputSource, parser.getXMLReader)
5964

60-
private def loadXML(source: InputSource, reader: XMLReader): T = {
61-
val result: FactoryAdapter = parse(source, reader)
65+
private def loadXML(inputSource: InputSource, reader: XMLReader): T = {
66+
val result: FactoryAdapter = parse(inputSource, reader)
6267
result.rootElem.asInstanceOf[T]
6368
}
64-
65-
private def loadXMLNodes(source: InputSource, reader: XMLReader): Seq[Node] = {
66-
val result: FactoryAdapter = parse(source, reader)
69+
70+
private def loadXMLNodes(inputSource: InputSource, reader: XMLReader): Seq[Node] = {
71+
val result: FactoryAdapter = parse(inputSource, reader)
6772
result.prolog ++ (result.rootElem :: result.epilogue)
6873
}
6974

70-
private def parse(source: InputSource, reader: XMLReader): FactoryAdapter = {
71-
if (source == null) throw new IllegalArgumentException("InputSource cannot be null")
75+
private def parse(inputSource: InputSource, xmlReader: XMLReader): FactoryAdapter = {
76+
if (inputSource == null) throw new IllegalArgumentException("InputSource cannot be null")
7277

7378
val result: FactoryAdapter = adapter
7479

75-
reader.setContentHandler(result)
76-
reader.setDTDHandler(result)
80+
xmlReader.setContentHandler(result)
81+
xmlReader.setDTDHandler(result)
7782
/* Do not overwrite pre-configured EntityResolver. */
78-
if (reader.getEntityResolver == null) reader.setEntityResolver(result)
83+
if (xmlReader.getEntityResolver == null) xmlReader.setEntityResolver(result)
7984
/* Do not overwrite pre-configured ErrorHandler. */
80-
if (reader.getErrorHandler == null) reader.setErrorHandler(result)
85+
if (xmlReader.getErrorHandler == null) xmlReader.setErrorHandler(result)
8186

8287
try {
83-
reader.setProperty("http://xml.org/sax/properties/lexical-handler", result)
88+
xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", result)
8489
} catch {
8590
case _: SAXNotRecognizedException =>
91+
case _: SAXNotSupportedException =>
8692
}
8793

8894
result.scopeStack = TopScope :: result.scopeStack
89-
reader.parse(source)
95+
xmlReader.parse(inputSource)
9096
result.scopeStack = result.scopeStack.tail
9197

9298
result
9399
}
94100

95-
/** loads XML from given InputSource. */
96-
def load(source: InputSource): T = loadXML(source, reader)
97-
98-
/** Loads XML from the given file, file descriptor, or filename. */
101+
/** Loads XML. */
102+
def load(inputSource: InputSource): T = loadXML(inputSource, reader)
103+
def loadFile(fileName: String): T = load(fromFile(fileName))
99104
def loadFile(file: File): T = load(fromFile(file))
100-
def loadFile(fd: FileDescriptor): T = load(fromFile(fd))
101-
def loadFile(name: String): T = load(fromFile(name))
102-
103-
/** loads XML from given InputStream, Reader, sysID, or URL. */
104-
def load(is: InputStream): T = load(fromInputStream(is))
105+
def load(url: URL): T = load(fromUrl(url))
106+
def load(sysId: String): T = load(fromSysId(sysId))
107+
def loadFile(fileDescriptor: FileDescriptor): T = load(fromFile(fileDescriptor))
108+
def load(inputStream: InputStream): T = load(fromInputStream(inputStream))
105109
def load(reader: Reader): T = load(fromReader(reader))
106-
def load(sysID: String): T = load(fromSysId(sysID))
107-
def load(url: URL): T = load(fromInputStream(url.openStream()))
108-
109-
/** Loads XML from the given String. */
110110
def loadString(string: String): T = load(fromString(string))
111111

112112
/** Load XML nodes, including comments and processing instructions that precede and follow the root element. */
113-
def loadNodes(source: InputSource): Seq[Node] = loadXMLNodes(source, reader)
113+
def loadNodes(inputSource: InputSource): Seq[Node] = loadXMLNodes(inputSource, reader)
114+
def loadFileNodes(fileName: String): Seq[Node] = loadNodes(fromFile(fileName))
114115
def loadFileNodes(file: File): Seq[Node] = loadNodes(fromFile(file))
115-
def loadFileNodes(fd: FileDescriptor): Seq[Node] = loadNodes(fromFile(fd))
116-
def loadFileNodes(name: String): Seq[Node] = loadNodes(fromFile(name))
117-
def loadNodes(is: InputStream): Seq[Node] = loadNodes(fromInputStream(is))
116+
def loadNodes(url: URL): Seq[Node] = loadNodes(fromUrl(url))
117+
def loadNodes(sysId: String): Seq[Node] = loadNodes(fromSysId(sysId))
118+
def loadFileNodes(fileDescriptor: FileDescriptor): Seq[Node] = loadNodes(fromFile(fileDescriptor))
119+
def loadNodes(inputStream: InputStream): Seq[Node] = loadNodes(fromInputStream(inputStream))
118120
def loadNodes(reader: Reader): Seq[Node] = loadNodes(fromReader(reader))
119-
def loadNodes(sysID: String): Seq[Node] = loadNodes(fromSysId(sysID))
120-
def loadNodes(url: URL): Seq[Node] = loadNodes(fromInputStream(url.openStream()))
121121
def loadStringNodes(string: String): Seq[Node] = loadNodes(fromString(string))
122122
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /