Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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
.net XmlSerializer:删除不必要的xsi和xsd命名空间_.net_Xml_Xml Serialization - Fatal编程技术网

.net XmlSerializer:删除不必要的xsi和xsd命名空间

.net XmlSerializer:删除不必要的xsi和xsd命名空间,.net,xml,xml-serialization,.net,Xml,Xml Serialization,有没有办法配置XmlSerializer,使其不会在根元素中写入默认名称空间 我得到的是: <?xml ...> <rootelement xmlns:xsi="..." xmlns:xsd="..."> </rootelement> 我想删除这两个xmlns声明 重复的:有一种替代方法-您可以在要序列化的类型中提供类型的成员。用属性装饰它。向该成员添加名称空间前缀和URI。然后,任何没有显式提供XmlSerializerNamespaces的序列化都将

有没有办法配置XmlSerializer,使其不会在根元素中写入默认名称空间

我得到的是:

<?xml ...>
<rootelement xmlns:xsi="..." xmlns:xsd="...">
</rootelement>

我想删除这两个xmlns声明


重复的

有一种替代方法-您可以在要序列化的类型中提供类型的成员。用属性装饰它。向该成员添加名称空间前缀和URI。然后,任何没有显式提供XmlSerializerNamespaces的序列化都将使用您在类型中输入的名称空间前缀+URI对

示例代码,假设这是您的类型:

[XmlRoot(Namespace = "urn:mycompany.2009")]
public class Person {
  [XmlAttribute] 
  public bool Known;
  [XmlElement]
  public string Name;
  [XmlNamespaceDeclarations]
  public XmlSerializerNamespaces xmlns;
}
您可以这样做:

var p = new Person
  { 
      Name = "Charley",
      Known = false, 
      xmlns = new XmlSerializerNamespaces()
  }
p.xmlns.Add("",""); // default namespace is emoty
p.xmlns.Add("c", "urn:mycompany.2009");
这将意味着该实例的任何序列化,如果没有指定自己的前缀+URI对集,将使用“urn:mycompany.2009”命名空间的“p”前缀。它还将省略xsi和xsd名称空间


这里的区别在于,您将XmlSerializerNamespaces添加到类型本身,而不是在调用XmlSerializer.Serialize()时显式使用它。这意味着,如果您类型的实例由您不拥有的代码(例如在webservices堆栈中)序列化,并且该代码没有显式提供XmlSerializerNamespaces,则序列化程序将使用实例中提供的命名空间。

因为Dave让我重复我的答案,我已经更新了这篇文章,并在上面提到的链接中重复了我的回答。此答案中使用的示例与另一个问题中使用的示例相同。下面的内容是逐字复制的


在阅读了微软的文档和一些在线解决方案之后,我发现了这个问题的解决方案。它与内置的
XmlSerializer
和通过
IXmlSerialiazble
定制的XML序列化一起工作

对于whit,我将使用到目前为止在这个问题的答案中使用的相同的
mytypewithnamespace
XML示例

[XmlRoot(“MyTypeWithNamespaces”,Namespace=“urn:Abracadabra”,IsNullable=false)]
公共类MyTypeWithNamespaces
{
//如下所述,根据Microsoft文档,如果该类公开了一个公共
//用修饰的XmlSerializerNamespaces类型的成员
//XmlNamespacesDeclarationAttribute,则XmlSerializer将利用这些属性
//序列化期间的命名空间。
公共MyTypeWithNamespaces()
{
此._名称空间=新的XmlSerializerNamespaces(新的XmlQualifiedName[]{
//不要这样做!!微软的文档明确表示它不受支持。
//它不会抛出任何异常,但在我的测试中,它并不总是有效的。
//新建XmlQualifiedName(string.Empty,string.Empty),//并且不要执行以下操作:
//新的XmlQualifiedName(“,”)
//这样做:
新的XmlQualifiedName(string.Empty,“urn:Abracadabra”)//默认名称空间
//在此处添加任何其他带有前缀的名称空间。
});
}
//如果有其他构造函数,请确保调用默认构造函数。
公共MyTypeWithNamespaces(字符串标签,int历元):此()
{
这个._label=标签;
这个._epoch=epoch;
}
//声明的命名空间与命名空间不同的元素
//属于封闭类型。
[xmlement(Namespace=“urn:Whoohoo”)]
公共字符串标签
{
获取{返回此。_label;}
设置{this.\u label=value;}
}
私有字符串标签;
//其标记将与属性名同名的元素。
//此外,此元素将继承封闭类型的命名空间。
公共信息时代
{
获取{返回此。_;}
设置{this.\u epoch=value;}
}
私人国际时代;
//根据Microsoft文档,您可以添加一些
//返回XmlSerializerNamespaces对象。它们使用公共字段,
//但这太草率了。所以我将使用一个有公共字段的私有备份字段
//getter属性。此外,根据文档,此属性的
//XmlSerializer,用XmlNamespace声明修饰它
//属性。
[xmlnamespace声明]
公共XmlSerializerNamespaces命名空间
{
获取{返回此。_名称空间;}
}
私有XmlSerializerNamespaces\u名称空间;
}
这节课就到此为止。现在,一些人反对在他们的类中的某个地方有一个
XmlSerializerNamespaces
对象;但正如您所看到的,我将其巧妙地隐藏在默认构造函数中,并公开了一个公共属性以返回名称空间

现在,当要序列化该类时,您将使用以下代码:

MyTypeWithNamespaces myType=新的MyTypeWithNamespaces(“myLabel”,42);
/******
好的,我只是觉得我可以这样做来缩短代码,所以我注释掉了
并将其替换为以下内容:
//为了使根元素具有正确的名称空间,必须使用此构造函数。
//如果需要对内部对象进行自定义序列化,可以使用缩短的构造函数。
XmlSerializer xs=新的XmlSerializer(typeof(MyTypeWithNamespaces),新的XmlAttributeOverrides(),
新类型[]{},新XmlRootAttribute(“MyTypeWithNamespaces”),“urn:Abracadabra”);
******/
/*****
根据@dbc,由于MyTypeWithNamespaces有一个XmlRootAttribute装饰类,
你可以不使用这个.ctor,而使用简单的
XmlSerializer(Type).ctor。
另外,注意不要在循环中使用序列化程序创建,因为它可能导致
由于序列化程序如何缓存(或不缓存…)而导致的大量内存问题。
有关更多详细信息,请参见@dbc的评论和SO Q&A的链接。
XmlSerializer xs=新的XmlSerializer(typeof(MyTypeWithNamespaces),
新的XmlRootAttribute(“MyTypeWithNamespaces”){Namespace=“urn:Abracadabra”});
****/
XmlSerializer xs=新的XmlSerializer(typeof(MyTypeWithNamespaces));
//我会用一个
var p = new Person
  { 
      Name = "Charley",
      Known = false, 
      xmlns = new XmlSerializerNamespaces()
  }
p.xmlns.Add("",""); // default namespace is emoty
p.xmlns.Add("c", "urn:mycompany.2009");
<MyTypeWithNamespaces>
    <Label xmlns="urn:Whoohoo">myLabel</Label>
    <Epoch>42</Epoch>
</MyTypeWithNamespaces>
<MyTypeWithNamespaces xmlns:w="urn:Whoohoo">
    <w:Label>myLabel</w:Label>
    <Epoch>42</Epoch>
</MyTypeWithNamespaces>
<MyTypeWithNamespaces>
    <Label>myLabel<Label>
    <Epoch>42</Epoch>
</MyTypeWithNamespaces>
<MyTypeWithNamespaces>
    <Label>myLabel<Label>
    <Epoch>42</Epoch>
</MyTypeWithNamespaces>
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        const string DEFAULT_NAMESPACE = "http://www.something.org/schema";
        var serializer = new XmlSerializer(typeof(Person), DEFAULT_NAMESPACE);
        var namespaces = new XmlSerializerNamespaces();
        namespaces.Add("", DEFAULT_NAMESPACE);

        using (var stream = new MemoryStream())
        {
            var someone = new Person
            {
                FirstName = "Donald",
                LastName = "Duck"
            };
            serializer.Serialize(stream, someone, namespaces);
            stream.Position = 0;
            using (var reader = new StreamReader(stream))
            {
                Console.WriteLine(reader.ReadToEnd());
            }
        }
    }
}
<?xml version="1.0"?>
<Person xmlns="http://www.something.org/schema">
  <FirstName>Donald</FirstName>
  <LastName>Duck</LastName>
</Person>
string xml = "<string xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">Hello, world!</string>";
xml = Regex.Replace(x, @" xmlns:.*?"".*?""", "");