⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlserver.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 2 页
字号:
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 + -