public override bool Add(VariableBindings result) { #if !DOTNET2 return(sink.Add(new VariableBindings(vars, result.Values))); #else Resource[] vals = new Resource[result.Values.Count]; result.Values.CopyTo(vals, 0); return(sink.Add(new VariableBindings(vars, vals))); #endif }
private static void ProcessResponse(string mimetype, Stream stream, object outputObj) { // If the user wants the output sent to a TextWriter, copy the response from // the response stream to the TextWriter. TODO: Get encoding from HTTP header. if (outputObj is TextWriter) { TextWriter tw = (TextWriter)outputObj; using (StreamReader reader = new StreamReader(stream, System.Text.Encoding.UTF8)) { char[] buffer = new char[512]; while (true) { int len = reader.Read(buffer, 0, buffer.Length); if (len <= 0) { break; } tw.Write(buffer, 0, len); if (Debug) { Console.Error.WriteLine(">> " + new String(buffer, 0, len)); } } } tw.Flush(); return; } // If the user wants a boolean out of this, then we're expecting a // SPARQL XML Results document with a boolean response element. if (outputObj is BooleanWrap) { BooleanWrap bw = (BooleanWrap)outputObj; if (mimetype != null && mimetype != "application/sparql-results+xml" && mimetype != "text/xml" && mimetype != "application/xml") { throw new ApplicationException("The result of the query was not a SPARQL Results document."); } XmlReader xmldoc = new XmlTextReader(stream); { // Move to the document element while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element) { break; } } // Just check that it has the right local name. if (xmldoc.LocalName != "sparql" || xmldoc.IsEmptyElement) { throw new ApplicationException("Invalid server response: Not a SPARQL results document."); } // Move to the next node. while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element) { break; } } // If it's a head node, skip it. if (xmldoc.LocalName == "head") { xmldoc.Skip(); // Move to the 'boolean' element, it better be next while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element) { break; } } } if (xmldoc.LocalName != "boolean") { throw new ApplicationException("Invalid server response: Missing 'boolean' element."); } string value = xmldoc.ReadElementString(); bw.value = (value == "true"); } if (Debug) { Console.Error.WriteLine(">> " + bw.value); } return; } // If the user wants statements out of the response, read it with an RDFReader. if (outputObj is StatementSink) { // If the mime type is application/sparql-results+xml, just try to // read it as if it were an RDF/XML MIME type. if (mimetype != null && mimetype == "application/sparql-results+xml") { mimetype = "text/xml"; } using (RdfReader reader = RdfReader.Create(mimetype, stream)) reader.Select((StatementSink)outputObj); if (Debug) { Console.Error.WriteLine(">> (read as statements)"); } return; } // If the user wants query result bindings, read the response XML. if (outputObj is QueryResultSink) { QueryResultSink sink = (QueryResultSink)outputObj; if (mimetype != null && mimetype != "application/sparql-results+xml" && mimetype != "text/xml") { throw new ApplicationException("The result of the query was not a SPARQL Results document."); } ArrayList variableNames = new ArrayList(); ArrayList variables = new ArrayList(); Variable[] variablesArray = null; Hashtable bnodes = new Hashtable(); XmlReader xmldoc = new XmlTextReader(stream); { // Move to the document element while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element) { break; } } // Just check that it has the right local name. if (xmldoc.LocalName != "sparql" || xmldoc.IsEmptyElement) { throw new ApplicationException("Invalid server response: Not a SPARQL results document."); } // Move to the 'head' node, it better be the first element while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element) { break; } } if (xmldoc.LocalName != "head" || xmldoc.IsEmptyElement) { throw new ApplicationException("Invalid server response: Missing head full element."); } // Read the head element while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element && xmldoc.LocalName == "variable") { if (xmldoc.GetAttribute("name") == null) { throw new ApplicationException("Invalid server response: Head/variable node missing name attribute."); } variableNames.Add(xmldoc.GetAttribute("name")); variables.Add(new Variable(xmldoc.GetAttribute("name"))); if (!xmldoc.IsEmptyElement) { xmldoc.Skip(); } } else if (xmldoc.NodeType == XmlNodeType.EndElement) { break; } } // Move to the 'results' element, it better be next while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element) { break; } } if (xmldoc.LocalName != "results") { throw new ApplicationException("Invalid server response: Missing results element."); } variablesArray = (Variable[])variables.ToArray(typeof(Variable)); sink.Init(variablesArray); // Read the results while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element && xmldoc.LocalName == "result") { // Read the bindings in this result Resource[] valuesArray = new Resource[variablesArray.Length]; while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Element && xmldoc.LocalName == "binding") { if (xmldoc.IsEmptyElement) { throw new ApplicationException("Invalid server response: Binding element empty."); } if (xmldoc.GetAttribute("name") == null) { throw new ApplicationException("Invalid server response: Result binding node missing name attribute."); } int vIndex = variableNames.IndexOf(xmldoc.GetAttribute("name")); if (vIndex == -1) { throw new ApplicationException("Invalid server response: Result binding name does not match a variable in the head."); } Resource value = null; while (xmldoc.Read()) { if (xmldoc.NodeType == XmlNodeType.Whitespace || xmldoc.NodeType == XmlNodeType.SignificantWhitespace) { continue; } if (xmldoc.NodeType == XmlNodeType.Element && xmldoc.LocalName == "uri") { value = new Entity(xmldoc.ReadElementString()); if (!xmldoc.IsEmptyElement) { xmldoc.Skip(); } } else if (xmldoc.NodeType == XmlNodeType.Element && xmldoc.LocalName == "literal") { string lang = xmldoc.XmlLang; if (lang == "") { lang = null; } string dt = xmldoc.GetAttribute("datatype"); value = new Literal(xmldoc.ReadElementString(), lang, dt); if (!xmldoc.IsEmptyElement) { xmldoc.Skip(); } } else if (xmldoc.NodeType == XmlNodeType.Element && xmldoc.LocalName == "bnode") { string id = xmldoc.ReadElementString(); if (bnodes.ContainsKey(id)) { value = (BNode)bnodes[id]; } else { value = new BNode(id); bnodes[id] = value; } if (!xmldoc.IsEmptyElement) { xmldoc.Skip(); } } else { throw new ApplicationException("Invalid server response: Invalid content in binding node."); } break; } if (value == null) { throw new ApplicationException("Invalid server response: Result binding value is invalid."); } valuesArray[vIndex] = value; } else if (xmldoc.NodeType == XmlNodeType.EndElement) { break; } } sink.Add(new VariableBindings(variablesArray, valuesArray)); if (Debug) { Console.Error.WriteLine(">> " + new VariableBindings(variablesArray, valuesArray)); } } else if (xmldoc.NodeType == XmlNodeType.EndElement) { break; } } sink.Finished(); } } }