Reputation: 10146
I have a problem. I wrote a program that converts some large amount of data into VML-GML
format. The problem is I need to use XmlWriter
... Now I have a problem with my method below:
private void StartDocument()
{
_writer.WriteStartDocument();
_writer.WriteStartElement("osgb", "FeatureCollection", "osgb");
_writer.WriteAttributeString("osgb", "xmlns", "http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1");
_writer.WriteAttributeString("gml", "xmlns", "http://www.opengis.net/gml");
_writer.WriteAttributeString("xsi", "xmlns", "http://www.w3.org/2001/XMLSchema-instance");
_writer.WriteAttributeString("schemaLocation", "xsi",
"http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1 http://www.ordnancesurvey.co.uk/oswebsite/xml/cmdschema/local/V1.1/CMDFeatures.xsd");
_writer.WriteAttributeString("fid", ""); // TODO: set fid here
_writer.WriteStartElement("gml", "description", "gml");
_writer.WriteValue("Ordnance Survey, (c) Crown Copyright. All rights reserved, 2011-03-02");
_writer.WriteEndElement(); // description
_writer.WriteElementString("osgb", "creationDate", "osgb", DateTime.Today.ToString("yyyy-MM-dd"));
}
How to write in namespaces correctly? I did this in that way and the output is:
<?xml version="1.0" encoding="utf-8"?>
<osgb:FeatureCollection p1:osgb="http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1"
p1:gml="http://www.opengis.net/gml"
p1:xsi="http://www.w3.org/2001/XMLSchema-instance"
p2:schemaLocation="http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1 http://www.ordnancesurvey.co.uk/oswebsite/xml/cmdschema/local/V1.1/CMDFeatures.xsd"
fid="" xmlns:p2="xsi" xmlns:p1="xmlns" xmlns:osgb="osgb">
And this is what I need:
<osgb:FeatureCollection xmlns:osgb="http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1 http://www.ordnancesurvey.co.uk/oswebsite/xml/cmdschema/local/V1.1/CMDFeatures.xsd"
fid="">
Why is that stupid XmlWriter
creating such things like p1
, p2
, etc.?
Btw. I tried to open my output file in the program that uses those VML-GML
files and it told me that the file is in a bad format. When I manually changed namespaces into the correct ones, everything was great.
How to correct it? Thanks in advance!
Upvotes: 1
Views: 4039
Reputation: 1499790
Why is that stupid XmlWriter creating such things like p1, p2, etc.?
You've got your attribute values the wrong way round, and you also need to specify another argument:
This:
_writer.WriteAttributeString("gml", "xmlns", "http://www.opengis.net/gml");
should be this:
_writer.WriteAttributeString("xmlns", "gml", null, "http://www.opengis.net/gml");
Additionally, your element writing code is incorrect. You're specifying the prefix when you should be specifying the namespace URI.
I believe this does what you need:
_writer.WriteStartDocument();
// The first argument here isn't really needed, but is changes whether a
// prefix is used or not
_writer.WriteStartElement("osgb", "FeatureCollection", "http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1");
_writer.WriteAttributeString("xmlns", "osgb", null, "http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1");
_writer.WriteAttributeString("xmlns", "gml", null, "http://www.opengis.net/gml");
_writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
_writer.WriteAttributeString("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance",
"http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1 http://www.ordnancesurvey.co.uk/oswebsite/xml/cmdschema/local/V1.1/CMDFeatures.xsd");
_writer.WriteAttributeString("fid", ""); // TODO: set fid here
_writer.WriteStartElement("description", "http://www.opengis.net/gml");
_writer.WriteValue("Ordnance Survey, (c) Crown Copyright. All rights reserved, 2011-03-02");
_writer.WriteEndElement(); // description
_writer.WriteElementString("creationDate", "http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1", DateTime.Today.ToString("yyyy-MM-dd"));
_writer.WriteEndElement();
(Personally I would use LINQ to XML, which makes all of this much simpler, but hey...)
As a hint, always assume that your code is wrong rather than the framework code, as a starting point. Regarding a framework class as "stupid" is likely to lead to you not looking at your own code with sufficient care.
EDIT: Here's working LINQ to XML code:
using System;
using System.Xml.Linq;
static class Test
{
static void Main()
{
XNamespace osgb = "http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1";
XNamespace gml = "http://www.opengis.net/gml";
XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
var doc = new XDocument(
new XElement(osgb + "FeatureCollection",
new XAttribute(XNamespace.Xmlns + "osgb", osgb),
new XAttribute(XNamespace.Xmlns + "gml", gml),
new XAttribute(XNamespace.Xmlns + "xsi", xsi),
new XAttribute(xsi + "schemaLocation", "http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1 http://www.ordnancesurvey.co.uk/oswebsite/xml/cmdschema/local/V1.1/CMDFeatures.xsd"),
new XAttribute("fid", ""),
new XElement(gml + "description", "Ordnance Survey ..."),
new XElement(osgb + "creationDate",
// TODO: Find a better way of doing this
DateTime.Today.ToString("yyyy-MM-dd"))));
Console.WriteLine(doc);
}
}
Output:
<osgb:FeatureCollection
xmlns:osgb="http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://namespaces.ordnancesurvey.co.uk/cmd/local/v1.1 http://www.ordnancesurvey.co.uk/oswebsite/xml/cmdschema/local/V1.1/CMDFeatures.xsd"
fid="">
<gml:description>Ordnance Survey ...</gml:description>
<osgb:creationDate>2012-10-19</osgb:creationDate>
</osgb:FeatureCollection>
Upvotes: 8