C# 在 Xml 序列化后删除空的 xmlns=""

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/616328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 10:22:31  来源:igfitidea点击:

Remove empty xmlns="" after Xml Serialization

c#.netxmlxml-serialization

提问by REA_ANDREW

So I am still asking questions about this topic :-(

所以我还在问关于这个话题的问题:-(

So I create an object, decorate it with the Xml Serialization Attributes, from what I have seen I add an empty namespace to the xml serialization namepsace collections so as not to get the superfluous attributes I did not intend to have.

所以我创建了一个对象,用 Xml 序列化属性装饰它,从我所看到的,我向 xml 序列化命名空间集合添加了一个空的命名空间,以免获得我不打算拥有的多余属性。

Edit:The attribute I mean are these:

编辑:我的意思是这些属性:

<url xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns="">

so it gives me two extra attributes.

所以它给了我两个额外的属性。

After further investigation if I change the beginning of the document from:**

经过进一步调查,如果我将文档的开头从:**

writer.WriteStartElement("urlset","http://www.sitemaps.org/schemas/sitemap/0.9");

to

writer.WriteStartElement("urlset");

**Then I do not get the empty xmlns="" attribute in the url tags. This is great BUT I do require that the root element have xmlns="http://www.sitemaps.org/schemas/sitemap/0.9", i.e.:

**然后我在 url 标签中没有得到空的 xmlns="" 属性。这很好,但我确实要求根元素具有xmlns="http://www.sitemaps.org/schemas/sitemap/0.9",即:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

But I still get an empty xmlns=""attribute in the serialized type.

但是我仍然xmlns=""在序列化类型中得到一个空属性。

[XmlRoot(ElementName = "url", Namespace="")]
public class SitemapNode
{
    [XmlElement(ElementName = "loc")]
    public string Location { get; set; }
    [XmlElement(ElementName = "lastmod")]
    public DateTime LastModified { get; set; }
    [XmlElement(ElementName = "changefreq")]
    public SitemapChangeFrequency ChangeFrequency { get; set; }
    [XmlElement(ElementName = "priority")]
    public decimal Priority { get; set; }

    public SitemapNode()
    {
        Location = String.Empty;
        LastModified = DateTime.Now;
        ChangeFrequency = SitemapChangeFrequency.monthly;
        Priority = 0.5M;
    }

    public SitemapNode(string location, DateTime lastModified, SitemapChangeFrequency changeFrequency, decimal priority)
    {
        Location = location;
        LastModified = lastModified;
        ChangeFrequency = changeFrequency;
        Priority = priority;
    }
}

Then I use the following to append to my XmlWriter:

然后我使用以下内容附加到我的 XmlWriter:

foreach (uk.co.andrewrea.SitemapNode node in List)
{
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add(String.Empty, String.Empty);
    Serializer.Serialize(Writer, node, ns);
}

This works out fine except I am left with an emtpy xmlns="" like this

这很好用,除非我留下了一个像这样的 emtpy xmlns=""

<url xmlns="">

Anyone any ideas? Again I can achieve this using the XmlTextWriter and the XmlDocument but I need to achieve it using the XmlWriter.

有人有什么想法吗?同样,我可以使用 XmlTextWriter 和 XmlDocument 来实现这一点,但我需要使用 XmlWriter 来实现它。

Any help is greatly appreciated.

任何帮助是极大的赞赏。

采纳答案by eglasius

This works (you just need them to be in the same namespace and you use the namespaces class so the writter doesn't confuse):

这是有效的(你只需要它们在同一个命名空间中并且你使用命名空间类,这样作者就不会混淆):

[TestMethod]
public void TestMethod3()
{
    var list = new []{new SitemapNode("1", DateTime.Now, 1), new SitemapNode("2", DateTime.Now.AddDays(1), 2)};
    var serializer = new XmlSerializer(typeof(SitemapNode));
    var st = new MemoryStream();
    using (var writer = XmlWriter.Create(st))
    {
        var ns = new XmlSerializerNamespaces();
        ns.Add("", "test");
        writer.WriteStartElement("test", "test");
        foreach (SitemapNode node in list)
        {
            serializer.Serialize(writer, node, ns);
        }
        writer.WriteEndElement();
    }
    st.Position = 0;
    TestContext.WriteLine(new StreamReader(st).ReadToEnd());
}


[XmlRoot(ElementName = "url", Namespace = "test")]
public class SitemapNode
{
    [XmlElement(ElementName = "loc")]
    public string Location { get; set; }
    [XmlElement(ElementName = "lastmod")]
    public DateTime LastModified { get; set; }
    [XmlElement(ElementName = "priority")]
    public decimal Priority { get; set; }

    public SitemapNode()
    {
        Location = String.Empty;
        LastModified = DateTime.Now;
        Priority = 0.5M;
    }

    public SitemapNode(string location, DateTime lastModified, decimal priority)
    {
        Location = location;
        LastModified = lastModified;
        Priority = priority;
    }
}

And the output is (based on your comments that is what you were looking for):

输出是(根据您的评论,这就是您要查找的内容):

    <?xml version="1.0" encoding="utf-8"?><test xmlns="test">
<url><loc>1</loc><lastmod>2009-03-05T13:35:54.6468-07:00</lastmod><priority>1</priority></url>
<url><loc>2</loc><lastmod>2009-03-06T13:35:54.6478-07:00</lastmod><priority>2</priority></url></test>

回答by cjk

Have you tried not specifying the namespace in your XmlRoot attribute?

您是否尝试过不在 XmlRoot 属性中指定命名空间?

I.e.:

IE:

[XmlRoot(ElementName = "url")]
public class SitemapNode
{ 
...
}

回答by Van Amburg

I was having trouble inserting a node into an existing document with multiple namespaces.

我在将节点插入具有多个命名空间的现有文档时遇到了问题。

No matter what I set the namespace to it would add the xmlns reference attribute every time no matter what. This was breaking something black boxed downstream.

无论我将命名空间设置为什么,每次都会添加 xmlns 引用属性。这打破了下游黑箱中的东西。

I eventually got around this by doing something like this.

我最终通过做这样的事情解决了这个问题。

XmlNode newNode = newDoc.SelectSingleNode(xpathQuery, manager);
newNode.Attributes.RemoveAll();   
node.ParentNode.InsertAfter(node.OwnerDocument.ImportNode(newNode, true), node);