删除由串行器创建空的xmlns [英] Remove empty xmlns created by serializer

查看:124
本文介绍了删除由串行器创建空的xmlns的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个添加服务引用...操作产生一个对象,我手动与通用串行我写了其序列。

I have an object generated by an "Add service reference..." operation and I am manually serializing it with a generic serializer I wrote.

我的问题是该数据契约有一些内部的对象。

My problem is that the data contract has some internal objects.

串行器添加了一个空的命名空间属性附加伤害到内部对象的开始标记。有什么办法来阻止这种情况发生?

The serializer adds an empty namespace atribute to the starting tag of the internal objects. Is there any way to stop this from happening?

推荐答案

怎么样让你的内部对象属于同一个命名空间的根?这样的话,这将是正确的,从后人省略的xmlns 声明。您可以使用 [汇编:ContractNamespace] 属性来覆盖在汇编所有合同的命名空间。参阅数据协定名称一个例子。

What about making your internal objects belong to the same namespace as the root? That way, it would be correct to omit the xmlns declaration from the descendants. You can use the [assembly: ContractNamespace] attribute to override the namespace for all contracts in your assembly. Refer to Data Contract Names for an example.

修改:下面一些例子的阐述

Edit: An elaboration with some examples below.

假设你手动构建一个XML文档,并且不指定任何的元素的命名空间。

Suppose you’re constructing an XML document manually, and don’t specify a namespace for any of your elements.

XDocument xmlDocument = new XDocument(
    new XElement("Book",
        new XElement("Title", "Animal Farm"),
        new XElement("Author", "George Orwell"),
        new XElement("Publisher",
            new XElement("Name", "Secker and Warburg"),
            new XElement("Location", "London"),
            new XElement("Founded", 1910))));
return xmlDocument.ToString();

生成的XML将如市场预期,是无效的命名空间声明的:

The generated XML would, as expected, be void of namespace declarations:

<Book>
  <Title>Animal Farm</Title>
  <Author>George Orwell</Author>
  <Publisher>
    <Name>Secker and Warburg</Name>
    <Location>London</Location>
    <Founded>1910</Founded>
  </Publisher>
</Book>



不过,如果你指定一个命名空间只为你的根元素,那么所有的子元素必须明确回复出默认的命名空间,使用 XML =声明。按照命名空间违约规则:

默认命名空间声明的作用域从它出现在相应的结束标记月底开始标记的开始延伸,不包括任何内在的范围默认命名空间声明。在一个空的标签的情况下,适用范围是标签本身

The scope of a default namespace declaration extends from the beginning of the start-tag in which it appears to the end of the corresponding end-tag, excluding the scope of any inner default namespace declarations. In the case of an empty tag, the scope is the tag itself.

因此​​,下面的代码(具有空间指定为根元素)...

Thus, the following code (having a namespace specified for the root element)…

XDocument xmlDocument = new XDocument(
    new XElement("{http://example.com/library}Book",
        new XElement("Title", "Animal Farm"),
        new XElement("Author", "George Orwell"),
        new XElement("Publisher",
            new XElement("Name", "Secker and Warburg"),
            new XElement("Location", "London"),
            new XElement("Founded", 1910))));
return xmlDocument.ToString();



...会给下面的XML:

…would give the following XML:

<Book xmlns="http://example.com/library">
  <Title xmlns="">Animal Farm</Title>
  <Author xmlns="">George Orwell</Author>
  <Publisher xmlns="">
    <Name>Secker and Warburg</Name>
    <Location>London</Location>
    <Founded>1910</Founded>
  </Publisher>
</Book>

请注意如何使用<的儿童;出版者> 元素不需要恢复了根的命名空间,因为他们继承其父无空间的宣言。

Note how the children of the <Publisher> element do not need to revert out of the root’s namespace, since they inherit the "no namespace" declaration from their parent.

要消除的xmlns =的声明,我们可以,为示范的缘故,分配相同的命名空间的所有的后代:

To eliminate the xmlns="" declarations, we could, for the sake of the demonstration, assign the same namespace to all descendants:

XDocument xmlDocument = new XDocument(
    new XElement("{http://example.com/library}Book",
        new XElement("{http://example.com/library}Title", "Animal Farm"),
        new XElement("{http://example.com/library}Author", "George Orwell"),
        new XElement("{http://example.com/library}Publisher",
            new XElement("{http://example.com/library}Name", "Secker and Warburg"),
            new XElement("{http://example.com/library}Location", "London"),
            new XElement("{http://example.com/library}Founded", 1910))));
return xmlDocument.ToString();

这将使在短短根申报(并含蓄的所有后代继承了命名空间的XML文档):

This would give an XML document with the namespace declared in just the root (and implicitly inherited in all descendants):

<Book xmlns="http://example.com/library">
  <Title>Animal Farm</Title>
  <Author>George Orwell</Author>
  <Publisher>
    <Name>Secker and Warburg</Name>
    <Location>London</Location>
    <Founded>1910</Founded>
  </Publisher>
</Book>

要模仿你的场景中涉及的Web服务,我们可以创建以下WCF服务。

To mimic your scenario involving a web service, we can create the following WCF service.

[DataContract]
public class Book
{
    [DataMember]
    public string Title { get; set; }
    [DataMember]
    public string Author { get; set; }
    [DataMember]
    public Publisher Publisher { get; set; }
}

[DataContract]
public class Publisher
{
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Location { get; set; }
    [DataMember]
    public short Founded { get; set; }
}

[ServiceContract]
public interface ILibraryService
{
    [OperationContract]
    Book GetBook();
}

public class LibraryService : ILibraryService
{
    public Book GetBook()
    {
        return new Book
        {
            Title = "Animal Farm",
            Author = "George Orwell",
            Publisher = new Publisher
            {
                Name = "Secker and Warburg",
                Location = "London",
                Founded = 1910,
            }
        };
    }
}

我们添加服务参考上述服务我们的客户端应用程序,消耗它的操作和串行化的结果,而在根括起来图书元素有一个明确的命名空间:

We add a service reference to the above service in our client application, consume its operation, and serialize the result whilst enclosing it in a root Books element having an explicit namespace:

using (var libraryClient = new LibraryServiceReference.LibraryServiceClient())
{
    var book = libraryClient.GetBook();

    var stringBuilder = new StringBuilder();
    using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder))
    {
        xmlWriter.WriteStartElement("Books", "http://example.com/library");
        var serializer = new XmlSerializer(book.GetType());
        serializer.Serialize(xmlWriter, book);
        xmlWriter.WriteEndElement();
    }

    return stringBuilder.ToString();
}

在这种情况下,内部元件图书包含一个的xmlns =声明。

In this case, the inner element Book contains an xmlns="" declaration.

<?xml version="1.0" encoding="utf-16"?>
<Books xmlns="http://example.com/library">
  <Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns="">
    <ExtensionData />
    <Author>George Orwell</Author>
    <Publisher>
      <ExtensionData />
      <Founded>1910</Founded>
      <Location>London</Location>
      <Name>Secker and Warburg</Name>
    </Publisher>
    <Title>Animal Farm</Title>
  </Book>
</Books>



如上所述,本的xmlns =可以通过设置图书元素的命名空间(以及它的后代),对应于root的。对于的XmlSerializer 类,所有元素的默认命名空间可以通过第二个参数的构造函数中指定。 (实际的技术将取决于其系列化的策略你使用的不同而不同。)

As explained above, this xmlns="" can be eliminated by setting the Book element’s namespace (and that of its descendants) to correspond to the root’s. For the XmlSerializer class, the default namespace for all elements can be specified through the second parameter to its constructor. (The actual technique would vary depending on which serialization strategy you’re using.)

using (var libraryClient = new LibraryServiceReference.LibraryServiceClient())
{
    var book = libraryClient.GetBook();

    var stringBuilder = new StringBuilder();
    using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder))
    {
        xmlWriter.WriteStartElement("Books", "http://example.com/library");
        var serializer = new XmlSerializer(book.GetType(), "http://example.com/library");
        serializer.Serialize(xmlWriter, book);
        xmlWriter.WriteEndElement();
    }

    return stringBuilder.ToString();
}



而这将使预期的结果:

And that would give the expected result:

<?xml version="1.0" encoding="utf-16"?>
<Books xmlns="http://example.com/library">
  <Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ExtensionData />
    <Author>George Orwell</Author>
    <Publisher>
      <ExtensionData />
      <Founded>1910</Founded>
      <Location>London</Location>
      <Name>Secker and Warburg</Name>
    </Publisher>
    <Title>Animal Farm</Title>
  </Book>
</Books>

这篇关于删除由串行器创建空的xmlns的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆