2 using System
.Collections
;
5 using System
.Xml
.XPath
;
9 namespace SemWeb
.Util
{
10 public class XPathSemWebNavigator
: XPathNavigator
{
12 NamespaceManager nsmgr
;
15 ArrayList stack
= new ArrayList();
18 private static Entity ExpandEntitiesOfType
= new Entity(null);
20 Entity rdfType
= NS
.RDF
+"type";
22 private class Position
{
24 public bool FirstChild
, LastChild
;
26 public Entity Predicate
;
27 public Resource Object
;
29 public Position
[] Children
;
32 private class NSWrap
: XsltContext
{
33 NamespaceManager nsmgr
;
35 public NSWrap(NamespaceManager nsmgr
) : base(new NameTable()) { this.nsmgr = nsmgr; }
37 public override bool HasNamespace (string prefix
) {
38 return LookupNamespace(prefix
) != null;
41 public override string LookupNamespace (string prefix
) {
42 return nsmgr
.GetNamespace(prefix
);
44 public override string LookupPrefix (string uri
) {
45 return nsmgr
.GetPrefix(uri
);
48 // These don't really do anything (yet?).
50 public override bool Whitespace
{
54 public override int CompareDocument (string baseUri
, string nextbaseUri
) {
55 return baseUri
.CompareTo(nextbaseUri
);
58 public override bool PreserveWhitespace (System
.Xml
.XPath
.XPathNavigator node
) {
62 public override IXsltContextFunction
ResolveFunction (string prefix
, string name
, System
.Xml
.XPath
.XPathResultType
[] ArgTypes
) {
66 public override IXsltContextVariable
ResolveVariable (string prefix
, string name
) {
71 public XPathSemWebNavigator(Store model
, NamespaceManager namespaces
) : this(ExpandEntitiesOfType
, model
, namespaces
, null) { }
73 public XPathSemWebNavigator(Entity root
, Store model
, NamespaceManager namespaces
) : this(root
, model
, namespaces
, null) { }
75 private XPathSemWebNavigator(Entity root
, Store model
, NamespaceManager namespaces
, string exapandThisPredicate
) {
78 if (!(namespaces
is SemWeb
.IO
.AutoPrefixNamespaceManager
))
79 namespaces
= new SemWeb
.IO
.AutoPrefixNamespaceManager(namespaces
);
80 this.nsmgr
= namespaces
;
81 nswrap
= new NSWrap(nsmgr
);
83 Position start
= new Position();
84 start
.FirstChild
= true;
85 start
.LastChild
= true;
86 start
.Predicate
= root
; // a trick to make sure the URI info for the root reflects the root
88 if (exapandThisPredicate
!= null)
89 Expand(start
, exapandThisPredicate
);
93 private XPathSemWebNavigator(XPathSemWebNavigator clone
) {
97 private void Expand(Position p
) {
101 private void Expand(Position p
, string expandOnlyThisPredicate
) {
102 if (!(p
.Object
is Entity
)) {
103 p
.Children
= new Position
[0];
107 ArrayList children
= new ArrayList();
110 if (p
.Object
== ExpandEntitiesOfType
) {
111 if (expandOnlyThisPredicate
== null) {
112 // Get a list of entities and their types.
113 foreach (Statement s
in model
.Select(new Statement(null, rdfType
, null))) {
114 if (!(s
.Object
is Entity
)) continue;
115 Position c
= new Position();
117 c
.Predicate
= (Entity
)s
.Object
;
118 c
.Object
= s
.Subject
;
122 foreach (Entity e
in model
.GetEntitiesOfType(expandOnlyThisPredicate
)) {
123 Position c
= new Position();
124 c
.Predicate
= expandOnlyThisPredicate
;
132 if (expandOnlyThisPredicate
== null || !expandOnlyThisPredicate
.StartsWith("!")) {
133 Statement q
= new Statement(
135 expandOnlyThisPredicate
== null ? (Entity
)null : (Entity
)expandOnlyThisPredicate
,
138 foreach (Statement s
in model
.Select(q
)) {
139 Position c
= new Position();
141 c
.Predicate
= s
.Predicate
;
147 if (expandOnlyThisPredicate
== null || expandOnlyThisPredicate
.StartsWith("!")) {
148 Statement q
= new Statement(
150 expandOnlyThisPredicate
== null ? (Entity
)null : (Entity
)expandOnlyThisPredicate
.Substring(1),
153 foreach (Statement s
in model
.Select(q
)) {
154 Position c
= new Position();
156 c
.Predicate
= "!" + s
.Predicate
;
157 c
.Object
= s
.Subject
;
164 p
.Children
= (Position
[])children
.ToArray(typeof(Position
));
166 if (p
.Children
.Length
> 0) {
167 p
.Children
[0].FirstChild
= true;
168 p
.Children
[p
.Children
.Length
-1].LastChild
= true;
172 public override string BaseURI { get { return ""; }
}
174 public override bool HasAttributes { get { return false; }
}
176 public override bool HasChildren { get { return true; }
}
178 public override bool IsEmptyElement { get { return false; }
}
180 public override string LocalName
{
183 if (current
.Predicate
== ExpandEntitiesOfType
)
185 if (current
.Predicate
.Uri
== null)
187 if (nsmgr
.Normalize(current
.Predicate
.Uri
, out p
, out l
))
189 throw new InvalidOperationException("The local name of " + current
.Predicate
.Uri
+ " could not be determined.");
193 public override string Name
{
195 if (current
.Predicate
== ExpandEntitiesOfType
)
197 if (current
.Predicate
.Uri
== null)
199 return nsmgr
.Normalize(current
.Predicate
.Uri
);
203 public override string NamespaceURI
{
206 if (current
.Predicate
.Uri
== null)
208 if (nsmgr
.Normalize(current
.Predicate
.Uri
, out p
, out l
))
209 return nsmgr
.GetNamespace(p
);
210 throw new InvalidOperationException("The namespace URI of " + current
.Predicate
.Uri
+ " could not be determined.");
214 public override XmlNameTable NameTable
{
220 public override XPathNodeType NodeType
{
222 if (stack
.Count
== 0)
223 return XPathNodeType
.Root
;
224 return XPathNodeType
.Element
;
228 public override string Prefix
{
231 if (nsmgr
.Normalize(current
.Predicate
.Uri
, out p
, out l
))
233 throw new InvalidOperationException("The prefix of " + current
.Predicate
.Uri
+ " could not be determined.");
237 public override string Value
{
239 if (current
.Predicate
== ExpandEntitiesOfType
)
241 if (current
.Object
is Literal
)
242 return ((Literal
)current
.Object
).Value
;
243 if (current
.Object
.Uri
== null)
245 return current
.Object
.Uri
;
249 public override string XmlLang { get { return ""; }
}
251 public override XPathNavigator
Clone () {
252 return new XPathSemWebNavigator(this);
255 //public virtual XmlNodeOrder ComparePosition (XPathNavigator nav)
257 public override string GetAttribute (string localName
, string namespaceURI
) {
261 public override string GetNamespace (string name
) {
262 return nsmgr
.GetNamespace(name
);
265 public override bool IsSamePosition (XPathNavigator other
) {
266 if (!(other
is XPathSemWebNavigator
)) return false;
267 XPathSemWebNavigator o
= (XPathSemWebNavigator
)other
;
268 return (o
.current
== current
);
271 public override bool MoveTo (XPathNavigator other
) {
272 XPathSemWebNavigator clone
= other
as XPathSemWebNavigator
;
273 if (clone
== null) return false;
274 this.model
= clone
.model
;
275 this.nsmgr
= clone
.nsmgr
;
276 this.nswrap
= clone
.nswrap
;
277 this.stack
= (ArrayList
)clone
.stack
.Clone();
278 this.current
= clone
.current
;
282 public override bool MoveToAttribute (string localName
, string namespaceURI
) { return false; }
284 public override bool MoveToNamespace (string name
) { return false; }
286 public override bool MoveToFirst () {
287 return MoveToFirstChild();
290 public override void MoveToRoot () {
291 if (stack
.Count
== 0) return;
292 current
= (Position
)stack
[0];
296 public override bool MoveToFirstAttribute () { return false; }
298 public override bool MoveToFirstChild () {
299 if (current
.Children
== null) Expand(current
);
300 if (current
.Children
.Length
== 0) return false;
302 current
= current
.Children
[0];
306 public override bool MoveToFirstNamespace (XPathNamespaceScope namespaceScope
) { return false; }
308 public override bool MoveToId (string id
) { return false; }
310 public override bool MoveToNext () {
311 if (current
.LastChild
) return false;
312 current
= ((Position
)stack
[stack
.Count
-1]).Children
[current
.Index
+1];
316 public override bool MoveToNextAttribute () { return false; }
318 public override bool MoveToNextNamespace (XPathNamespaceScope namespaceScope
) { return false; }
320 public override bool MoveToParent () {
321 if (stack
.Count
== 0) return false;
322 current
= (Position
)stack
[stack
.Count
-1];
323 stack
.RemoveAt(stack
.Count
-1);
327 public override bool MoveToPrevious () {
328 if (current
.FirstChild
) return false;
329 current
= ((Position
)stack
[stack
.Count
-1]).Children
[current
.Index
-1];
333 public override XPathNodeIterator
SelectChildren (string name
, string namespaceURI
) {
334 if (current
.Object
is Literal
) throw new InvalidOperationException("The navigator is positioned on a literal element.");
335 return new XPathSemWebNavigator((Entity
)current
.Object
, model
, nsmgr
, namespaceURI
+ name
).SelectChildren(XPathNodeType
.All
);
338 public override XPathNodeIterator
Select (XPathExpression expr
) {
339 expr
.SetContext(nswrap
);
340 return base.Select(expr
);
343 public override object Evaluate (XPathExpression expr
) {
344 expr
.SetContext(nswrap
);
345 return base.Evaluate(expr
);
348 public override object Evaluate (XPathExpression expr
, XPathNodeIterator context
) {
349 expr
.SetContext(nswrap
);
350 return base.Evaluate(expr
, context
);