1

我有个问题。我编写了一个程序,可以将大量数据转换为VML-GML格式。问题是我需要使用XmlWriter......现在我的方法有问题:

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"));
}

如何正确写入命名空间?我这样做了,输出是:

<?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">

这就是我需要的:

<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="">

为什么那个愚蠢的人会XmlWriter创造像p1,p2等这样的东西?

顺便提一句。我试图在使用这些VML-GML文件的程序中打开我的输出文件,它告诉我文件格式错误。当我手动将命名空间更改为正确的命名空间时,一切都很好。

如何纠正它?提前致谢!

4

1 回答 1

8

为什么那个愚蠢的 XmlWriter 会创建像 p1、p2 等这样的东西?

你的属性值是错误的,你还需要指定另一个参数:

这个:

_writer.WriteAttributeString("gml", "xmlns", "http://www.opengis.net/gml");

应该是这样的:

_writer.WriteAttributeString("xmlns", "gml", null, "http://www.opengis.net/gml");

此外,您的元素编写代码不正确。当您应该指定命名空间 URI 时,您正在指定前缀。

我相信这可以满足您的需求:

_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();

(我个人会使用 LINQ to XML,这让这一切变得更简单,但是嘿......)

作为提示,始终假设您的代码是错误的,而不是框架代码,作为起点。将框架类视为“愚蠢”可能会导致您没有足够小心地查看自己的代码。

编辑:这是工作 LINQ to XML 代码:

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);
   }
}

输出:

<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>
于 2012-10-19T14:45:15.303 回答