如何忽略XML命名空间?

5

我有一个测试xml文件,长这样:

<Person>
  <ContactInfo>
   ...
  <ContactInfo>
</Person>

当我尝试反序列化时,一切都很顺利。 但问题是有时候这个xml文件的结构不同 - 有时会添加xml命名空间。

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

现在我进行序列化时,出现了一个 IOnvalidOperationException: "XML文档(1, 2)中有一个错误"。内部异常消息说 <Person xmlns='http://tempuri.org/PaymentInformationXml.xsd'> 是不被预期的。

是否有人可以帮助我解决这个问题呢?


你正在使用什么工具进行反序列化? - Jim Mischel
你的示例XML和错误信息不一致;xsi / xsd只是命名空间别名 - 它们不会改变任何内容。你可以基本忽略这两个。但是,xmlns ='... blah ...'非常重要。请澄清:这是否在您的XML中?如果是,则必须提前告诉XmlSerializer。 - Marc Gravell
3个回答

6

在XML中,命名空间是非常重要的(与可互换的名称空间不同)。如果Person在该命名空间中,你必须将其告知:

[XmlRoot(Namespace="http://tempuri.org/PaymentInformationXml.xsd")]
public class Person {...}

1

请查看XmlSerializerNamespaces

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

可以直接在 XmlSerializer 上控制默认命名空间

XmlSerializer xs = new XmlSerializer(typeof(Person), "http://tempuri.org/PaymentInformationXml.xsd");

...但是你的问题有点不清楚问题来自哪里。

请检查你的Person类的[XmlType]属性:

[XmlType(Namespace="http://tempuri.org/PaymentInformationXml.xsd")]
public class Person
{
    //...
}

您的Person类型的命名空间需要与序列化时使用的命名空间保持一致。


问题不在于xsi/xsd,而是xmlns=,这意味着XmlSerializerNamespaces在这里无效。 - Marc Gravell

1

这里有一篇关于 XML 的文章在这里

我也偶然发现了这段代码:(非常有帮助)

XmlDocument stripDocumentNamespace(XmlDocument oldDom)
{
// Remove all xmlns:* instances from the passed XmlDocument
// to simplify our xpath expressions.
XmlDocument newDom = new XmlDocument();
newDom.LoadXml(System.Text.RegularExpressions.Regex.Replace(
oldDom.OuterXml, @"(xmlns:?[^=]*=[""][^""]*[""])", "",
System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline)
);
return newDom;
} 

希望这能有所帮助


你忘记了前缀。 - Suncat2000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接