📄 xmlserver.cs
字号:
using System;
using System.Xml;
using System.IO;
using System.Collections;
namespace Rdf
{
/// <summary>
/// Parse XML requests and store/fetch data in store database
/// </summary>
public class XmlServer
{
VersionedStorage store;
TextWriter writer;
public XmlServer(VersionedStorage store, TextWriter writer)
{
this.store = store;
this.writer = writer;
}
public Thing ImportObject(XmlReader reader, String parentUri)
{
String localName = reader.LocalName;
String name = reader.NamespaceURI + localName;
String uri = null;
bool IsEmptyElement = reader.IsEmptyElement;
ArrayList props = new ArrayList();
while (reader.MoveToNextAttribute())
{
String attrName = reader.NamespaceURI + reader.LocalName;
if (XmlSymbols.Uri == attrName)
{
uri = reader.Value;
}
else
{
props.Add(CreateProperty(attrName, reader.Value));
}
}
if (uri == null)
{
uri = parentUri + '/' + localName;
}
if (!IsEmptyElement)
{
while (reader.Read() && reader.NodeType != XmlNodeType.EndElement)
{
if (reader.NodeType == XmlNodeType.Element)
{
props.Add(ImportProperty(reader, uri));
}
}
}
return store.CreateObject(uri, name, (NameVal[])props.ToArray(typeof(NameVal)));
}
public NameVal ImportProperty(XmlReader reader, String parentUri)
{
String localName = reader.LocalName;
String name = reader.NamespaceURI + localName;
object val = null;
if (reader.HasAttributes)
{
String uri = reader.GetAttribute("resource", XmlSymbols.RDF);
if (uri == null)
{
val = ImportObject(reader, parentUri).vh;
}
else
{
val = store.GetObject(uri);
if (val == null)
{
throw new XmlException("Object with URI '" + uri + "' is not found");
}
if (!reader.IsEmptyElement)
{
while (reader.Read() && reader.NodeType != XmlNodeType.EndElement);
}
}
}
else
{
if (reader.IsEmptyElement)
{
throw new XmlException("Property '" + name + "' value is not defined");
}
while (reader.Read() && reader.NodeType != XmlNodeType.EndElement)
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
{
ArrayList props = new ArrayList();
String uri = parentUri + '/' + localName;
do
{
if (reader.NodeType == XmlNodeType.Element)
{
props.Add(ImportProperty(reader, uri));
}
} while (reader.Read() && reader.NodeType != XmlNodeType.EndElement);
Thing thing = store.CreateObject(uri, name, (NameVal[])props.ToArray(typeof(NameVal)));
return new NameVal(name, thing.vh);
}
case XmlNodeType.Text:
val = ConvertValue(reader.Value);
continue;
}
}
}
return new NameVal(name, val);
}
public void ReadThingPattern(XmlReader reader)
{
SearchKind kind = SearchKind.LatestVersion;
DateTime timestamp = DateTime.Now;
String name = reader.NamespaceURI + reader.LocalName;
String uri = null;
String type = XmlSymbols.Thing.Equals(name) ? null : name;
ArrayList props = new ArrayList();
bool IsEmptyElement = reader.IsEmptyElement;
int depth = 0;
while(reader.MoveToNextAttribute())
{
string attrName = reader.NamespaceURI + reader.LocalName;
string attrVal = reader.Value;
switch (attrName)
{
case XmlSymbols.Uri:
uri = reader.Value;
break;
case XmlSymbols.Before:
timestamp = DateTime.Parse(attrVal);
kind = SearchKind.LatestBefore;
break;
case XmlSymbols.After:
timestamp = DateTime.Parse(attrVal);
kind = SearchKind.OldestAfter;
break;
case XmlSymbols.All:
kind = bool.Parse(attrVal) ? SearchKind.AllVersions : SearchKind.LatestVersion;
break;
case XmlSymbols.Depth:
depth = int.Parse(attrVal);
break;
default:
props.Add(new NameVal(attrName, ConvertPattern(attrVal)));
break;
}
}
if (!IsEmptyElement)
{
while (reader.Read() && reader.NodeType != XmlNodeType.EndElement)
{
if (reader.NodeType == XmlNodeType.Element)
{
props.Add(ReadPropertyPatterns(reader));
}
}
}
foreach (Thing thing in store.Search(type, uri, (NameVal[])props.ToArray(typeof(NameVal)), kind, timestamp))
{
DumpObject(thing, writer, 1, kind, timestamp, depth);
}
}
static string GetQualifiedName(string uri, TextWriter writer)
{
int col = uri.LastIndexOf(':');
int hash = uri.LastIndexOf('#');
int path = uri.LastIndexOf('/');
int namespaceLen = Math.Max(Math.Max(col, hash), path);
writer.Write('<');
if (namespaceLen > 0)
{
string prefix = uri.Substring(0, namespaceLen+1);
string name = uri.Substring(namespaceLen+1);
switch (prefix)
{
case Symbols.RDF:
name = "rdf:" + name;
break;
case Symbols.RDFS:
name = "rdfs:" + name;
break;
case Symbols.NS:
name = "vr:" + name;
break;
default:
writer.Write(name + " xmlns=\"" + prefix + "\"");
return name;
}
uri = name;
}
writer.Write(uri);
return uri;
}
static void DumpObject(Thing thing, TextWriter writer, int indent, SearchKind kind, DateTime timestamp, int depth)
{
WriteTab(writer, indent);
string typeName = GetQualifiedName(thing.type.vh.uri, writer);
writer.WriteLine(" rdf:about=\"" + thing.vh.uri + "\" vr:timestamp=\"" + thing.timestamp + "\">");
foreach (PropVal pv in thing.props)
{
object val = pv.val;
if (val is VersionHistory)
{
VersionHistory ptr = (VersionHistory)val;
if (kind != SearchKind.AllVersions)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -