public void Save(IGraph g, TextWriter output, bool leaveOpen) { using (var writer = XmlWriter.Create(output, new XmlWriterSettings { Indent = true, CloseOutput = !leaveOpen, OmitXmlDeclaration = true })) { var n = g.Nodes.Union(g.Triples.PredicateNodes).UriNodes(); var n2 = string.Join(",", n.Select(nn => nn.Uri.AbsoluteUri)); var a = FixedQueryController.ExecuteNamedSparql("label", new Dictionary <string, string> { { "id", n2 } }) as SparqlResultSet; var d = a.ToDictionary(r => r["subject"] as IUriNode, r => r["label"].AsValuedNode().AsString()); writer.WriteStartElement("html"); writer.WriteStartElement("head"); writer.WriteRaw(@" <link rel=""stylesheet"" href=""https://unpkg.com/[email protected]/dist/leaflet.css"" integrity=""sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="" crossorigin="""" /> <script src=""https://unpkg.com/[email protected]/dist/leaflet.js"" integrity=""sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="" crossorigin=""""></script> <script src=""https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.3.1/leaflet-omnivore.min.js""></script> <script> window.addEventListener(""load"", onLoad); function onLoad() { document.querySelectorAll(""data.map"").forEach(createMap); } function createMap(mapElement) { const map = L.map(mapElement); L.tileLayer(""https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}"", { id: ""mapbox.streets"", accessToken: ""pk.eyJ1IjoiaHVudHAiLCJhIjoiY2l6cXY3NjZpMDAxZzJybzF0aDBvdHRlZCJ9.k1zL5uDY7eUvuSiw3Rdrkw"" }).addTo(map); const geometryLayer = omnivore.wkt.parse(mapElement.value); geometryLayer.addTo(map); map.fitBounds(geometryLayer.getBounds()); } </script> <style> body { margin: 0; font-family: sans-serif; } table { width: 100%; border-collapse: collapse; } thead th { height: 50px; position: sticky; top: 0; z-index: 1; background-color: black; color: white; text-align: left; padding-left: 20px; } tr.divider { border-top: 1px solid; } tr.divider:nth-child(1) { border-top: none; } td { padding: 20px; vertical-align: top; } div { position: sticky; left: 20px; top: 70px; } data { font-family: monospace; } data.map { height: 180px; display: block } a { text-decoration: none; } a:hover { text-decoration: underline; } </style> <script type=""text/javascript""> var appInsights=window.appInsights||function(a){ function b(a){c[a]=function(){var b=arguments;c.queue.push(function(){c[a].apply(c,b)})}}var c={config:a},d=document,e=window;setTimeout(function(){var b=d.createElement(""script"");b.src=a.url||""https://az416426.vo.msecnd.net/scripts/a/ai.0.js"",d.getElementsByTagName(""script"")[0].parentNode.appendChild(b)});try{c.cookie=d.cookie}catch(a){}c.queue=[];for(var f=[""Event"",""Exception"",""Metric"",""PageView"",""Trace"",""Dependency""];f.length;)b(""track""+f.pop());if(b(""setAuthenticatedUserContext""),b(""clearAuthenticatedUserContext""),b(""startTrackEvent""),b(""stopTrackEvent""),b(""startTrackPage""),b(""stopTrackPage""),b(""flush""),!a.disableExceptionTracking){f=""onerror"",b(""_""+f);var g=e[f];e[f]=function(a,b,d,e,h){var i=g&&g(a,b,d,e,h);return!0!==i&&c[""_""+f](a,b,d,e,h),i}}return c }({ instrumentationKey:""c0960a0f-30ad-4a9a-b508-14c6a4f61179"", cookieDomain:"".parliament.uk"" }); window.appInsights=appInsights,appInsights.queue&&0===appInsights.queue.length&&appInsights.trackPageView(); </script> "); writer.WriteEndElement(); // head writer.WriteStartElement("body"); writer.WriteStartElement("table"); HtmlWriter.WriteTHead(writer); HtmlWriter.WriteTBody(g, writer, d); writer.WriteEndElement(); // table writer.WriteEndElement(); // body writer.WriteEndElement(); // html } }
private static void WriteNode(XmlWriter writer, Triple triple, Dictionary <IUriNode, string> labelMapping, TripleSegment segment) { var node = HtmlWriter.GetNode(triple, segment); if (node is IUriNode uriNode) { var uri = uriNode.Uri.AbsoluteUri; if (segment == TripleSegment.Object && HtmlWriter.IsPhoto(triple.Predicate)) { var id = Global.InstanceUri.MakeRelativeUri(uriNode.Uri); writer.WriteStartElement("a"); writer.WriteAttributeString("href", "resource?uri=" + WebUtility.UrlEncode(uri)); writer.WriteStartElement("data"); writer.WriteAttributeString("value", uri); writer.WriteStartElement("img"); writer.WriteAttributeString("src", $"https://api.parliament.uk/photo/{id}.jpeg?crop=MCU_3:2&width=260&quality=80"); writer.WriteEndElement(); // data writer.WriteEndElement(); // img writer.WriteEndElement(); // a return; } if (!labelMapping.TryGetValue(uriNode, out string label)) { label = uri .Replace(Global.SchemaUri.AbsoluteUri, string.Empty) .Replace(Global.InstanceUri.AbsoluteUri, string.Empty) .Replace(RdfSpecsHelper.RdfType, "a") .Replace("http://example.com/", string.Empty) .Replace("http://www.w3.org/2000/01/rdf-schema#", string.Empty) .Replace("http://www.w3.org/2002/07/owl#", string.Empty) .Replace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", string.Empty); } writer.WriteStartElement("div"); writer.WriteStartElement("a"); writer.WriteAttributeString("href", "resource?uri=" + WebUtility.UrlEncode(uri)); writer.WriteStartElement("data"); writer.WriteAttributeString("value", uri); writer.WriteString(label); writer.WriteEndElement(); // data writer.WriteEndElement(); // a writer.WriteEndElement(); // div return; } if (node is IBlankNode blankNode) { if (segment == TripleSegment.Subject) { writer.WriteStartElement("div"); writer.WriteStartElement("a"); writer.WriteAttributeString("name", blankNode.InternalID); writer.WriteFullEndElement(); // a writer.WriteString(blankNode.InternalID); writer.WriteEndElement(); // div return; } if (segment == TripleSegment.Object) { writer.WriteStartElement("a"); writer.WriteAttributeString("href", "#" + blankNode.InternalID); writer.WriteString(blankNode.InternalID); writer.WriteEndElement(); // a return; } } if (node is ILiteralNode literalNode) { var datatype = literalNode.DataType?.AbsoluteUri; if (datatype == XmlSpecsHelper.XmlSchemaDataTypeDate) { if (DateTimeOffset.TryParse(literalNode.Value, out DateTimeOffset dto)) { writer.WriteStartElement("time"); writer.WriteString(dto.ToString("yyyy-MM-dd")); writer.WriteEndElement(); // time return; } } if (datatype == "http://www.opengis.net/ont/geosparql#wktLiteral") { if (HtmlWriter.IsGeography(triple.Predicate)) { writer.WriteStartElement("data"); writer.WriteAttributeString("class", "map"); writer.WriteAttributeString("value", literalNode.Value); writer.WriteEndElement(); // data return; } } writer.WriteString(literalNode.Value); return; } writer.WriteString(node.ToString()); }