+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 :
#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__;
nsNodeName_ = nsNodeName__;
nsNodeUri_ = nsNodeUri__;
+ idTable_ = idTable__;
+
this.nameTable = nameTable;
}
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 ();
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
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;
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;
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.)
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 ();
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;
}
{
#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__;
nsNodeName_ = nsNodeName__;
nsNodeUri_ = nsNodeUri__;
+ idTable_ = idTable__;
+
this.nameTable = nameTable;
this.MoveToRoot ();
this.document = document;
// 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;
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;
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