#.net #xml #serialization #deserialization #xml-namespaces
#.net #xml #сериализация #десериализация #xml-пространства имен
Вопрос:
У меня есть тестовый 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'>
не ожидалось.
Итак, кто-нибудь может мне помочь с этим?
Комментарии:
1. Что вы используете для десериализации?
2. Ваш пример XML и сообщение об ошибке несовместимы; xsi / xsd — это просто псевдонимы пространства имен — они ничего не меняют. Вы можете в значительной степени игнорировать эти два. Тем не менее,
xmlns='...blah...'
это очень важно. Пожалуйста, уточните: это в вашем XML или нет? Если это так, вы должны заранее сообщить XmlSerializer
Ответ №1:
Пространство имен является фундаментальным в XML (в отличие от пространств имен, которые взаимозаменяемы). Если пользователь находится в этом пространстве имен, вы должны сообщить ему:
[XmlRoot(Namespace="http://tempuri.org/PaymentInformationXml.xsd")]
public class Person {...}
Ответ №2:
И я также наткнулся на этот фрагмент кода: (очень полезный)
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;
}
надеюсь, это может помочь
Комментарии:
1. Вы забыли префиксы.
Ответ №3:
Проверьте пространства имен 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
classes [XmlType]
:
[XmlType(Namespace="http://tempuri.org/PaymentInformationXml.xsd")]
public class Person
{
//...
}
Пространство имен для вашего Person
типа должно соответствовать тому, которое вы используете при сериализации.
Комментарии:
1. Проблема не в xsi / xsd, а скорее в xmlns=, что означает, что XmlSerializerNamespaces здесь ничего не делает,