2003-08-14 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 14 Aug 2003 15:35:29 +0000 (15:35 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 14 Aug 2003 15:35:29 +0000 (15:35 -0000)
* DTMXPathDocument.cs,
  DTMXPathDocumentBuilder.cs,
  DTMXPathNavigator.cs :
  - Implemented ID support using XmlValidatingReader.
  - Prefix should be String.Empty even if XmlReader.Prefix is null.

svn path=/trunk/mcs/; revision=17328

mcs/class/System.XML/Mono.Xml.XPath/ChangeLog
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocument.cs
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathDocumentBuilder.cs
mcs/class/System.XML/Mono.Xml.XPath/DTMXPathNavigator.cs

index 58bcee375bf704f920c972f5e62a05b84a02e93a..a9378174221905a0faf70eff0cbb25788514cb1c 100644 (file)
@@ -1,3 +1,11 @@
+2003-08-14  Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+       * DTMXPathDocument.cs,
+         DTMXPathDocumentBuilder.cs,
+         DTMXPathNavigator.cs :
+         - Implemented ID support using XmlValidatingReader.
+         - Prefix should be String.Empty even if XmlReader.Prefix is null.
+
 2003-07-23  Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
 
        * DTMXPathDocumentBuilder.cs :
index 67a4c01c13d12926435bc74a99d6baee8b1f078a..8498e07791f35ca0089c78696ece7dd3f7aa1f2e 100644 (file)
@@ -22,7 +22,36 @@ namespace Mono.Xml.XPath
 
 #region ctor.
 
-               public DTMXPathDocument (XmlNameTable nameTable, int [] firstChild__, int [] parent__, int [] firstAttribute__, int [] previousSibling__, int [] nextSibling__, int [] depth__, int [] position__, XPathNodeType [] nodeType__, string [] baseUri__, bool [] isEmptyElement__, string [] localName__, string [] namespaceUri__, string [] prefix__, string [] value__, string [] xmlLang__, int [] namespaceNode__, object [] schemaType__, int [] ownerElement__, int [] nextAttribute__, string [] attrLocalName__, string [] attrPrefix__, string [] attrNsUri__, string [] attrValue__, object [] attrSchemaType__, int [] nsDeclaredElement__, int [] nextNsNode__, string [] nsNodeName__, string [] nsNodeUri__)
+               public DTMXPathDocument (XmlNameTable nameTable,
+                       int [] firstChild__,
+                       int [] parent__,
+                       int [] firstAttribute__,
+                       int [] previousSibling__,
+                       int [] nextSibling__,
+                       int [] depth__,
+                       int [] position__,
+                       XPathNodeType [] nodeType__,
+                       string [] baseUri__,
+                       bool [] isEmptyElement__,
+                       string [] localName__,
+                       string [] namespaceUri__,
+                       string [] prefix__,
+                       string [] value__,
+                       string [] xmlLang__,
+                       int [] namespaceNode__,
+                       object [] schemaType__,
+                       int [] ownerElement__,
+                       int [] nextAttribute__,
+                       string [] attrLocalName__,
+                       string [] attrPrefix__,
+                       string [] attrNsUri__,
+                       string [] attrValue__,
+                       object [] attrSchemaType__,
+                       int [] nsDeclaredElement__,
+                       int [] nextNsNode__,
+                       string [] nsNodeName__,
+                       string [] nsNodeUri__,
+                       Hashtable idTable__)
                {
                        firstChild_ = firstChild__;
                        parent_ = parent__;
@@ -57,6 +86,8 @@ namespace Mono.Xml.XPath
                        nsNodeName_ = nsNodeName__;
                        nsNodeUri_ = nsNodeUri__;
 
+                       idTable_ = idTable__;
+
                        this.nameTable = nameTable;
                }
 
@@ -67,7 +98,7 @@ namespace Mono.Xml.XPath
                public XPathNavigator CreateNavigator ()
                {
                        if (root == null) {
-                               root = new DTMXPathNavigator (this, nameTable, firstChild_, parent_, firstAttribute_, previousSibling_, nextSibling_, depth_, position_, nodeType_, baseUri_, isEmptyElement_, localName_, namespaceUri_, prefix_, value_, xmlLang_, namespaceNode_, schemaType_, ownerElement_, nextAttribute_, attrLocalName_, attrPrefix_, attrNsUri_, attrValue_, attrSchemaType_, nsDeclaredElement_, nextNsNode_, nsNodeName_, nsNodeUri_);
+                               root = new DTMXPathNavigator (this, nameTable, firstChild_, parent_, firstAttribute_, previousSibling_, nextSibling_, depth_, position_, nodeType_, baseUri_, isEmptyElement_, localName_, namespaceUri_, prefix_, value_, xmlLang_, namespaceNode_, schemaType_, ownerElement_, nextAttribute_, attrLocalName_, attrPrefix_, attrNsUri_, attrValue_, attrSchemaType_, nsDeclaredElement_, nextNsNode_, nsNodeName_, nsNodeUri_, idTable_);
                                return root;
                        } else
                                return root.Clone ();
@@ -116,10 +147,8 @@ namespace Mono.Xml.XPath
                string [] nsNodeName_;          // NS prefix.
                string [] nsNodeUri_;           // NS uri.
 
-               // ID-Key
-               // [string attribute-name] -> idTable
                // idTable [string value] -> int nodeId
-               readonly Hashtable idTableTable;
+               readonly Hashtable idTable_;
 
 #endregion
 
index 4a49e35ba629b012e8d4abb1f2b11e8ce66f7f95..95b7489b30869a05b9a63c996896f9c164e9bee2 100644 (file)
@@ -19,29 +19,43 @@ namespace Mono.Xml.XPath
        public class DTMXPathDocumentBuilder
        {
                public DTMXPathDocumentBuilder (string url)
-                       : this (url, XmlSpace.None)
+                       : this (url, XmlSpace.None, false)
                {
                }
 
                public DTMXPathDocumentBuilder (string url, XmlSpace space)
-                       : this (new XmlTextReader (url), space)
+                       : this (url, space, false)
+               {
+               }
+
+               public DTMXPathDocumentBuilder (string url, XmlSpace space, bool supportID)
+                       : this (new XmlTextReader (url), space, supportID)
                {
                }
 
                public DTMXPathDocumentBuilder (XmlReader reader)
-                       : this (reader, XmlSpace.None)
+                       : this (reader, XmlSpace.None, false)
                {
                }
 
                public DTMXPathDocumentBuilder (XmlReader reader, XmlSpace space)
+                       : this (reader, space, false)
+               {
+               }
+
+               public DTMXPathDocumentBuilder (XmlReader reader, XmlSpace space, bool supportID)
                {
                        this.xmlReader = reader;
+                       if (supportID)
+                               this.validatingReader = reader as XmlValidatingReader;
                        this.xmlSpace = xmlSpace;
                        this.nameTable = reader.NameTable;
                        Compile ();
                }
                
+               bool supportID;
                XmlReader xmlReader;
+               XmlValidatingReader validatingReader;
                XmlSpace xmlSpace;
                XmlNameTable nameTable;
                int defaultCapacity = 100;
@@ -88,6 +102,9 @@ namespace Mono.Xml.XPath
                int [] nextNsNode_ = new int [100];
                string [] nsNodeName_ = new string [100];
                string [] nsNodeUri_ = new string [100];
+
+               // idTable [string value] -> int nodeId
+               Hashtable idTable_;
 #endregion
 
                int nodeIndex;
@@ -129,12 +146,15 @@ namespace Mono.Xml.XPath
                                nsDeclaredElement_,
                                nextNsNode_,
                                nsNodeName_,
-                               nsNodeUri_
+                               nsNodeUri_,
+                               idTable_
                        );
                }
 
                public void Compile ()
                {
+                       idTable_ = new Hashtable ();
+
                        // index 0 is dummy. No node (including Root) is assigned to this index
                        // So that we can easily compare index != 0 instead of index < 0.
                        // (Difference between jnz or jbe in 80x86.)
@@ -284,20 +304,31 @@ namespace Mono.Xml.XPath
                                                if (lastNsIndexInCurrent == 0)
                                                        namespaceNode_ [nodeIndex] = nsIndex;
                                                this.AddNsNode (nodeIndex,
-                                                       xmlReader.Prefix == "" ?
+                                                       (xmlReader.Prefix == null || xmlReader.Prefix == String.Empty) ?
                                                                "" : xmlReader.LocalName,
                                                        xmlReader.Value);
                                                lastNsIndexInCurrent = nsIndex;
                                        } else {
                                                // add attribute node.
                                                attributeIndex ++;
-                                               this.AddAttribute (nodeIndex, xmlReader.LocalName, xmlReader.NamespaceURI, xmlReader.Prefix, xmlReader.Value, null);
+                                               this.AddAttribute (nodeIndex, xmlReader.LocalName, xmlReader.NamespaceURI, xmlReader.Prefix != null ? xmlReader.Prefix : String.Empty, xmlReader.Value, null);
                                                if (firstAttributeIndex == 0)
                                                        firstAttributeIndex = attributeIndex;
                                                else
                                                        nextAttribute_ [attributeIndex - 1] = attributeIndex;
                                                // dummy for "current" attribute.
                                                nextAttribute_ [attributeIndex] = 0;
+
+                                               // Identity infoset
+                                               if (validatingReader != null) {
+                                                       XmlSchemaDatatype dt = validatingReader.SchemaType as XmlSchemaDatatype;
+                                                       if (dt == null) {
+                                                               XmlSchemaType xsType = validatingReader.SchemaType as XmlSchemaType;
+                                                               dt = xsType.Datatype;
+                                                       }
+                                                       if (dt != null && dt.TokenizedType == XmlTokenizedType.ID)
+                                                               idTable_.Add (xmlReader.Value, nodeIndex);
+                                               }
                                        }
                                } while (xmlReader.MoveToNextAttribute ());
                                xmlReader.MoveToElement ();
@@ -326,35 +357,35 @@ namespace Mono.Xml.XPath
                private void SetObjectArrayLength (ref object [] a, int length)
                {
                        object [] arr = new object [length];
-                       Array.Copy (a, arr, System.Math.Min (a.Length, length));
+                       Array.Copy (a, arr, Math.Min (a.Length, length));
                        a = arr;
                }
 
                private void SetBoolArrayLength (ref bool [] a, int length)
                {
                        bool [] bArr = new bool [length];
-                       Array.Copy (a, bArr, System.Math.Min (a.Length, length));
+                       Array.Copy (a, bArr, Math.Min (a.Length, length));
                        a = bArr;
                }
 
                private void SetXPathNodeTypeArrayLength (ref XPathNodeType [] a, int length)
                {
                        XPathNodeType [] arr = new XPathNodeType [length];
-                       Array.Copy (a, arr, System.Math.Min (a.Length, length));
+                       Array.Copy (a, arr, Math.Min (a.Length, length));
                        a = arr;
                }
 
                private void SetIntArrayLength (ref int [] a, int length)
                {
                        int [] intArr = new int [length];
-                       Array.Copy (a, intArr, System.Math.Min (a.Length, length));
+                       Array.Copy (a, intArr, Math.Min (a.Length, length));
                        a = intArr;
                }
 
                private void SetStringArrayLength (ref string [] a, int length)
                {
                        string [] strArr = new string [length];
-                       Array.Copy (a, strArr, System.Math.Min (a.Length, length));
+                       Array.Copy (a, strArr, Math.Min (a.Length, length));
                        a = strArr;
                }
 
index 690c373061ef40e6668a651c06ce52d6ae42f082..2e26a0cec8141dbe52d85e6156e2150709490250 100644 (file)
@@ -19,7 +19,23 @@ namespace Mono.Xml.XPath
        {
 
 #region Copy of XPathDocument
-               public DTMXPathNavigator (DTMXPathDocument document, XmlNameTable nameTable, int [] firstChild__, int [] parent__, int [] firstAttribute__, int [] previousSibling__, int [] nextSibling__, int [] depth__, int [] position__, XPathNodeType [] nodeType__, string [] baseUri__, bool [] isEmptyElement__, string [] localName__, string [] namespaceUri__, string [] prefix__, string [] value__, string [] xmlLang__, int [] namespaceNode__, object [] schemaType__, int [] ownerElement__, int [] nextAttribute__, string [] attrLocalName__, string [] attrPrefix__, string [] attrNsUri__, string [] attrValue__, object [] attrSchemaType__, int [] nsDeclaredElement__, int [] nextNsNode__, string [] nsNodeName__, string [] nsNodeUri__)
+               public DTMXPathNavigator (DTMXPathDocument document,
+                       XmlNameTable nameTable, 
+                       int [] firstChild__, int [] parent__, 
+                       int [] firstAttribute__, int [] previousSibling__, 
+                       int [] nextSibling__, int [] depth__, 
+                       int [] position__, XPathNodeType [] nodeType__,
+                       string [] baseUri__, bool [] isEmptyElement__, 
+                       string [] localName__, string [] namespaceUri__, 
+                       string [] prefix__, string [] value__, 
+                       string [] xmlLang__, int [] namespaceNode__, 
+                       object [] schemaType__, int [] ownerElement__, 
+                       int [] nextAttribute__, string [] attrLocalName__, 
+                       string [] attrPrefix__, string [] attrNsUri__, 
+                       string [] attrValue__, object [] attrSchemaType__, 
+                       int [] nsDeclaredElement__, int [] nextNsNode__, 
+                       string [] nsNodeName__, string [] nsNodeUri__,
+                       Hashtable idTable__)
                {
                        firstChild_ = firstChild__;
                        parent_ = parent__;
@@ -54,6 +70,8 @@ namespace Mono.Xml.XPath
                        nsNodeName_ = nsNodeName__;
                        nsNodeUri_ = nsNodeUri__;
 
+                       idTable_ = idTable__;
+
                        this.nameTable = nameTable;
                        this.MoveToRoot ();
                        this.document = document;
@@ -61,7 +79,17 @@ namespace Mono.Xml.XPath
 
                // Copy constructor including position informations.
                public DTMXPathNavigator (DTMXPathNavigator org)
-                       : this (org.document, org.nameTable, org.firstChild_, org.parent_, org.firstAttribute_, org.previousSibling_, org.nextSibling_, org.depth_, org.position_, org.nodeType_, org.baseUri_, org.isEmptyElement_, org.localName_, org.namespaceUri_, org.prefix_, org.value_, org.xmlLang_, org.namespaceNode_, org.schemaType_, org.ownerElement_, org.nextAttribute_, org.attrLocalName_, org.attrPrefix_, org.attrNsUri_, org.attrValue_, org.attrSchemaType_, org.nsDeclaredElement_, org.nextNsNode_, org.nsNodeName_, org.nsNodeUri_)
+                       : this (org.document, org.nameTable,
+                       org.firstChild_, org.parent_, org.firstAttribute_,
+                       org.previousSibling_, org.nextSibling_, org.depth_,
+                       org.position_, org.nodeType_, org.baseUri_,
+                       org.isEmptyElement_, org.localName_, org.namespaceUri_,
+                       org.prefix_, org.value_, org.xmlLang_,
+                       org.namespaceNode_, org.schemaType_, org.ownerElement_, 
+                       org.nextAttribute_, org.attrLocalName_, org.attrPrefix_, 
+                       org.attrNsUri_, org.attrValue_, org.attrSchemaType_, 
+                       org.nsDeclaredElement_, org.nextNsNode_, org.nsNodeName_,
+                       org.nsNodeUri_, org.idTable_)
                {
                        currentIsNode = org.currentIsNode;
                        currentIsAttr = org.currentIsAttr;
@@ -110,10 +138,12 @@ namespace Mono.Xml.XPath
                string [] nsNodeName_;          // NS prefix.
                string [] nsNodeUri_;           // NS uri.
 
-               // ID-Key (considered xsd:keyref for XPath 2.0)
+               // ID table
+               Hashtable idTable_;
+
+               // Key table (considered xsd:keyref for XPath 2.0)
                Hashtable keyRefTable;  // [string key-name] -> idTable
                                        // idTable [string value] -> int nodeId
-                                       // keyname="" for ID
 #endregion
 
                bool currentIsNode;
@@ -448,9 +478,19 @@ namespace Mono.Xml.XPath
                        return moveToSpecifiedNamespace (cur, namespaceScope);
                }
 
+               // Note that this support is extension to XPathDocument.
+               // XPathDocument does not support ID reference.
                public override bool MoveToId (string id)
                {
-                       return MoveToKeyRef ("", id);
+//                     return MoveToKeyRef ("", id);
+                       if (idTable_.ContainsKey (id)) {
+                               currentNode = (int) idTable_ [id];
+                               currentIsNode = true;
+                               currentIsAttr = false;
+                               return true;
+                       }
+                       else
+                               return false;
                }
 
                // This is extension for XPath 2.0