Skip to content

Commit 9926876

Browse files
buraqadriaanm
authored andcommitted
modified xml parsing
1 parent 958d994 commit 9926876

File tree

3 files changed

+99
-53
lines changed

3 files changed

+99
-53
lines changed

sources/scala/xml/parsing/ConstructingHandler.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ class ConstructingHandler extends MarkupHandler[Node] {
1010

1111
def attributeNamespaceDecl(pos: int, uri: String) = NamespaceDecl(uri);
1212

13-
def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[String,AttribValue], args: mutable.Buffer[Node]) = {
13+
def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[Pair[String,String],AttribValue], args: mutable.Buffer[Node]) = {
1414

1515
var attrs = new Array[Attribute](attrMap1.size);
1616
{
1717
var i = 0;
1818
val it = attrMap1.elements;
1919
while( it.hasNext ) {
20-
val Pair(ke:String, va: AttribValue) = it.next;
20+
val Pair(Pair(uri:String, key:String), va: AttribValue) = it.next;
2121
va match {
22-
case CDataValue(str) => attrs( i ) = Attribute("",ke,str);
22+
case CDataValue(str) => attrs( i ) = Attribute(uri, key, str);
2323
}
2424
i = i + 1;
2525
}

sources/scala/xml/parsing/MarkupHandler.scala

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@ import scala.collection.mutable ;
55
import scala.collection.Map ;
66

77
/** class that handles markup - provides callback methods to MarkupParser */
8-
abstract class MarkupHandler[MarkupType] {
8+
abstract class MarkupHandler[A] {
99

1010
/** a stack of prefix namespace mappings */
1111
protected val prefixStack =
1212
new mutable.Stack[immutable.Map[String,String]]();
1313

1414
/** mapping from prefixes to namespaces */
1515
var namespace: immutable.Map[String,String] =
16-
new immutable.TreeMap[String,String].update("","");
16+
new immutable.TreeMap[String,String]
17+
.update("","")
18+
.update("xml","http://www.w3.org/XML/1998/namespace");
19+
20+
21+
var tmpPrefix: mutable.Map[String, String] =
22+
new mutable.HashMap[String,String];
1723

1824
/** returns prefix of the qualified name if any */
1925
final def namespacePrefix(name: String): Option[String] = {
@@ -23,10 +29,10 @@ abstract class MarkupHandler[MarkupType] {
2329

2430
/** removes xmlns attributes from attr as a side effect, and returns a prefix
2531
* map resulting from them
26-
*/
27-
final def namespaceDecl(aMap: mutable.Map[String, AttribValue]): Map[String, String] = {
32+
* /
33+
final def namespaceDecl1(aMap: mutable.Map[String, AttribValue]): Map[String, String] = {
2834
val setNS = new mutable.HashMap[String, String];
29-
/* DEBUG */
35+
/ * DEBUG * /
3036
val attrIt = aMap.keys;
3137
while( attrIt.hasNext ) {
3238
val z = attrIt.next;
@@ -47,40 +53,46 @@ abstract class MarkupHandler[MarkupType] {
4753
}
4854
setNS;
4955
}
56+
*/
57+
58+
/** removes xmlns attributes from attr as a side effect, and returns a prefix
59+
* map resulting from them
60+
*/
61+
final def internal_namespaceDecl(prefix:String, uri:String): Unit = {
62+
tmpPrefix.update(prefix, uri);
63+
}
5064

5165
def attributeCDataValue(pos: int, str:String): AttribValue;
5266
def attributeNamespaceDecl(pos: int, uri: String): AttribValue;
5367

54-
def attribute(pos: int, key: String, value:String): AttribValue =
55-
if( key.startsWith("xmlns"))
56-
attributeNamespaceDecl(pos, value);
57-
else
58-
attributeCDataValue(pos, value);
68+
def attribute(pos: int, uri: String, key: String, value:String): AttribValue =
69+
attributeCDataValue(pos, value);
5970

6071
/** be careful to copy everything from attrMap1, as it will change
61-
* @param attrMap1 the attribute map.
72+
* @param pos the position in the sourcefile
73+
* @param uri the namespace uri
74+
* @param label the tag name
75+
* @param attrMap1 the attribute map, from Pair(uri,label) to target
76+
* @param args the children of this element
6277
*/
63-
def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[String,AttribValue], args: mutable.Buffer[MarkupType]): Iterable[MarkupType];
78+
def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[Pair[String,String],AttribValue], args: mutable.Buffer[A]): Iterable[A];
6479

65-
def charData(pos: Int, txt: String ): Iterable[MarkupType];
66-
def procInstr(pos: Int, target: String, txt: String): Iterable[MarkupType];
67-
def comment(pos: Int, comment: String ): Iterable[MarkupType];
68-
def entityRef(pos: Int, n: String): Iterable[MarkupType];
80+
def charData(pos: Int, txt: String ): Iterable[A];
81+
def procInstr(pos: Int, target: String, txt: String): Iterable[A];
82+
def comment(pos: Int, comment: String ): Iterable[A];
83+
def entityRef(pos: Int, n: String): Iterable[A];
6984

70-
def text(pos: Int, txt:String): Iterable[MarkupType];
85+
def text(pos: Int, txt:String): Iterable[A];
7186

7287

73-
def internal_startPrefixMapping(pref: Map[String, String]) = {
74-
if( !pref.isEmpty ) {
75-
this.prefixStack.push( this.namespace );
76-
this.namespace = this.namespace incl pref;
77-
}
88+
def internal_startPrefixMapping: Unit = {
89+
this.prefixStack.push( this.namespace );
90+
this.namespace = this.namespace incl tmpPrefix;
91+
tmpPrefix.clear;
7892
}
7993

80-
def internal_endPrefixMapping(pref: Map[String, String]): Unit = {
81-
if( !pref.isEmpty ) {
82-
this.namespace = prefixStack.pop;
83-
}
94+
def internal_endPrefixMapping: Unit = {
95+
this.namespace = prefixStack.pop;
8496
}
8597

8698
}

sources/scala/xml/parsing/MarkupParser.scala

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ abstract class MarkupParser[MarkupType] {
4242
protected var aMap: mutable.Map[String,AttribValue] = _;
4343

4444
final val noChildren = new mutable.ListBuffer[MarkupType];
45-
final val noAttribs = new mutable.HashMap[String, AttribValue];
45+
final val noAttribs = new mutable.HashMap[Pair[String,String], AttribValue];
4646

4747
//var xEmbeddedBlock = false;
4848

@@ -84,33 +84,66 @@ abstract class MarkupParser[MarkupType] {
8484
* | `{` scalablock `}`
8585
*/
8686
def xAttributes = {
87-
val aMap = new mutable.HashMap[String,AttribValue];
87+
val aMap = new mutable.HashMap[Pair[String,String],Pair[Int,String]];
8888
while( xml.Parsing.isNameStart( ch )) {
89-
val key = xName;
89+
val pos = this.pos;
90+
val key1 = xName;
91+
var prefix: String = _;
92+
var key: String = _;
93+
94+
handle.namespacePrefix(key1) match {
95+
case Some(x @ "xmlns") =>
96+
prefix = null;
97+
key = key1.substring(x.length()+1, key1.length());
98+
case Some(x) =>
99+
prefix = x;
100+
key = key1.substring(x.length()+1, key1.length());
101+
case _ =>
102+
if( key1 == "xmlns" ) {
103+
prefix= null;
104+
key = "";
105+
} else {
106+
prefix = "";
107+
key = key1
108+
}
109+
}
90110
xEQ;
91111
val delim = ch;
92112
val pos1 = pos;
93-
val value:AttribValue = ch match {
113+
val value:String = ch match {
94114
case '"' | '\'' =>
95115
nextch;
96116
val tmp = xAttributeValue(delim);
97117
nextch;
98-
handle.attribute( pos1, key, tmp );
99-
/*case '{' if enableEmbeddedExpressions =>
100-
nextch;
101-
handle.attributeEmbedded(pos1, xEmbeddedExpr);*/
118+
tmp;
102119
case _ =>
103-
reportSyntaxError( "' or \" delimited attribute value or '{' scala-expr '}' expected" );
104-
handle.attribute( pos1, key, "<syntax-error>" )
120+
reportSyntaxError( "' or \" delimited attribute value expected" );
121+
"<syntax-error>"
105122
};
106-
// well-formedness constraint: unique attribute names
107-
if (aMap.contains(key))
108-
reportSyntaxError( "attribute " + key + " may only be defined once" );
109-
aMap.update( key, value );
123+
124+
if(prefix == null) {
125+
handle.internal_namespaceDecl(key, value);
126+
} else {
127+
aMap.update( Pair(prefix,key), Pair(pos,value) );
128+
}
129+
110130
if ((ch != '/') && (ch != '>'))
111131
xSpace;
112-
};
113-
aMap
132+
}
133+
// @todo, iterate over attributes, replace prefix, call handleAttribute.
134+
handle.internal_startPrefixMapping;
135+
val aMap1 = new mutable.HashMap[Pair[String,String],AttribValue];
136+
val it = aMap.elements;
137+
while( it.hasNext ) {
138+
val x @ Pair(Pair(pref,key),Pair(pos,value)) = it.next;
139+
val uri = handle.namespace(pref);
140+
val qkey = Pair(uri, key);
141+
// well-formedness constraint: unique attribute names
142+
if (aMap.contains(qkey))
143+
reportSyntaxError( "attribute " + key + " may only be defined once" );
144+
aMap1.update(qkey, handle.attribute(pos, uri, key, value));
145+
}
146+
aMap1
114147
}
115148

116149
/** attribute value, terminated by either ' or ". value may not contain &lt;.
@@ -136,15 +169,16 @@ abstract class MarkupParser[MarkupType] {
136169
* [40] STag ::= '&lt;' Name { S Attribute } [S]
137170
* [44] EmptyElemTag ::= '&lt;' Name { S Attribute } [S]
138171
*/
139-
protected def xTag: Pair[String, mutable.Map[String,AttribValue]] = {
172+
protected def xTag: Pair[String, mutable.Map[Pair[String,String],AttribValue]] = {
140173
val elemqName = xName;
141174

142175
xSpaceOpt;
143-
val aMap: mutable.Map[String,AttribValue] =
176+
val aMap: mutable.Map[Pair[String,String],AttribValue] =
144177
if(xml.Parsing.isNameStart( ch )) {
145178
xAttributes;
146179
} else {
147-
noAttribs
180+
handle.internal_startPrefixMapping;
181+
noAttribs;
148182
};
149183
Pair(elemqName, aMap);
150184
}
@@ -318,13 +352,13 @@ abstract class MarkupParser[MarkupType] {
318352
if(ch == '/') { // empty element
319353
xToken('/');
320354
xToken('>');
321-
pref = handle.namespaceDecl( aMap );
322-
handle.internal_startPrefixMapping( pref );
355+
//pref = handle.namespaceDecl( aMap );
356+
//handle.internal_startPrefixMapping( pref );
323357
noChildren;
324358
} else { // element with content
325359
xToken('>');
326-
pref = handle.namespaceDecl( aMap );
327-
handle.internal_startPrefixMapping( pref );
360+
//pref = handle.namespaceDecl( aMap );
361+
//handle.internal_startPrefixMapping( pref );
328362
val tmp = content;
329363
xEndTag( qname );
330364
tmp;
@@ -339,7 +373,7 @@ abstract class MarkupParser[MarkupType] {
339373
handle.namespace("");
340374
}
341375
val res = handle.element(pos1, uri, name, aMap, ts );
342-
handle.internal_endPrefixMapping( pref );
376+
handle.internal_endPrefixMapping;
343377
res
344378
}
345379

0 commit comments

Comments
 (0)