Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除由序列化程序创建的空XMLN_C#_Xml_Wcf - Fatal编程技术网

C# 删除由序列化程序创建的空XMLN

C# 删除由序列化程序创建的空XMLN,c#,xml,wcf,C#,Xml,Wcf,我有一个由“添加服务引用…”操作生成的对象,我正在使用我编写的通用序列化程序手动序列化它 我的问题是数据契约有一些内部对象 序列化程序向内部对象的起始标记添加一个空命名空间atribute。有没有办法阻止这种情况发生?如果您可以控制序列化程序,则始终可以添加空名称空间,以确保输出XML中省略xmlns。例如: var serializer = new XmlSerializer(target.GetType()); var ns = new XmlSerializerNamespaces();

我有一个由“添加服务引用…”操作生成的对象,我正在使用我编写的通用序列化程序手动序列化它

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


序列化程序向内部对象的起始标记添加一个空命名空间atribute。有没有办法阻止这种情况发生?

如果您可以控制序列化程序,则始终可以添加空名称空间,以确保输出XML中省略xmlns。例如:

var serializer = new XmlSerializer(target.GetType()); 
var ns = new XmlSerializerNamespaces(); 
ns.Add("",""); 
serializer.Serialize(xmlWriter, target, ns); 

请注意,

让内部对象与根对象属于同一名称空间怎么样?这样,从子体中省略
xmlns
声明是正确的。您可以使用
[assembly:ContractNamespace]
属性覆盖程序集中所有协定的命名空间。有关示例,请参阅

编辑:下面是一些示例的详细说明

假设您正在手动构建一个XML文档,并且没有为任何元素指定名称空间

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将没有命名空间声明:

<Book>
  <Title>Animal Farm</Title>
  <Author>George Orwell</Author>
  <Publisher>
    <Name>Secker and Warburg</Name>
    <Location>London</Location>
    <Founded>1910</Founded>
  </Publisher>
</Book>
…将提供以下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>
这将提供一个XML文档,其名称空间仅在根中声明(并在所有子体中隐式继承):

我们在客户机应用程序中向上述服务添加服务引用,使用其操作,并序列化结果,同时将其封装在具有显式命名空间的根
Books
元素中:

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();
}
在这种情况下,内部元素
Book
包含
xmlns=”“
声明

<?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>
这将产生预期的结果:

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

乔治·奥威尔
1910
伦敦
塞克和沃伯格
畜牧场

如果您使用的是
[DataContract]
,这可能有点离题,可能不适用。相反,这适用于从WSDL生成的代理代码(在具有java端点的互操作环境中,我们被告知xmlns=”“无效)。所以我把它放在那里以防万一

当设置为
System.Xml.Schema.XmlSchemaForm.Unqualified
时,
xmlementAttribute.Form
属性会导致WCF请求中的子成员输出xmlns=”“

[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string MyProperty {
     get; set;
}
它产生了一些类似于

<MyObject xmlns="http://some.namespance">
   <MyProperty xmlns="">My value goes here</MyProperty>
</MyObject>
这就产生了:

<MyObject xmlns="http://some.namespance">
   <MyProperty>My value goes here</MyProperty>
</MyObject>

我的价值在这里

我不确定您是否可以在导入wsdl引用时更改此行为,或者wsdl是否应该更改,但我最终直接编辑了生成的代理代码(这肯定不理想),但实现了我的直接目标。

为什么会出现问题?如果元素位于默认名称空间中,则
xmlns=“”
是正确的。xmlns=“”可能是正确的,但我无法控制接收此消息的WS,它将无法与它们一起工作。有什么方法可以删除它们吗?如果xmlns=”“破坏了读取XML的代码,那么它就严重破坏了,并且有一个非常严重的bug需要修复。它无法读取一些基本的、正确的XML。一定要做一个好邻居,告诉代码的所有者他们应该修复它来处理默认名称空间。你说的“我编写的通用序列化程序”是什么意思?如果它是一个自定义序列化程序,那么您不是自己定义了它的行为吗?我试过了,但它从所有元素中删除了xmlns。我需要根目录来保持xmlns(它不是空的)。我最终使用了数据协定序列化程序而不是XmlSerializer,这使得它可以开箱即用,但非常感谢您的回答。获得赏金。谢谢!:-)我本来想提到
DataContractSerializer
,但我(错误地)认为服务本身为其数据契约声明了空(或不正确)名称空间(例如
[DataContract(Namespace=”“)]
),这在客户端使用该序列化程序是不容易绕过的
XmlSerializer
忽略数据约定上声明的名称空间,允许您替换自己的名称空间。无论如何,很高兴你找到了一个简单的解决方案!
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();
}
<?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>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string MyProperty {
     get; set;
}
<MyObject xmlns="http://some.namespance">
   <MyProperty xmlns="">My value goes here</MyProperty>
</MyObject>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.None)]
public string MyProperty {
    get; set;
}
<MyObject xmlns="http://some.namespance">
   <MyProperty>My value goes here</MyProperty>
</MyObject>