У меня проблемы с десериализацией XML с "неопределенным" префиксом пространства имен, который действительно определен.
Мы опубликовали внутренний веб-сервис на C #, который обслуживает множество клиентов. IDE нового клиента настаивает на объявлении xsi: type для каждого элемента в своем выводе XML, и они не могут отключить эту «функцию».
XML-сообщение, которое они создают, выглядит следующим образом, где «пространство имен» - это правильное пространство имен.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<myOperation xsi:type="ns1:namespace" xmlns="namespace" xmlns:ns1="namespace">
<inputString xsi:type="xsd:string">ABCDEF</inputString>
<books xsi:type="ns1:booksType">
<bookID xsi:type="xsd:string">ABC123</bookID>
<bookID xsi:type="xsd:string">DEF456</bookID>
</books>
<!-- ... snip... -->
</myOperation>
</soapenv:Body>
<books>
- это в основном массив строк.
Метод службы принимает как XmlNode, но XmlSerializer выдает ошибку «префикс« ns1 »не определен». (Он определен в родительском узле, но, видимо, этого недостаточно.) У меня похожая проблема с использованием wsdl.exe для генерации классов и десериализации ввода для меня.
Использование XmlNamespaceManager для указания префиксов не кажется правильным - похоже на магические числа, и я не могу предсказать, какой префикс в любом случае объявит данный потребитель. Есть ли способ справиться с этим, не удаляя атрибуты (books.Attributes.RemoveAll)? Это тоже не особенно элегантно.
Я обнаружил, что books.OuterXML не содержит никакой информации для 'ns1', если только я не взломал входящий элемент, чтобы использовать этот префикс (), поэтому я могу понять, почему он жалуется, но я пока не понимаю, почему ' ns1 'не распознается из предыдущего определения выше.
Большое спасибо за любую помощь или, по крайней мере, образование, которое кто-то может предоставить.
Редактирует: все работает нормально, если я изменяю <books>
на префикс, т.е. <ns1:books xsi:type="ns1:booksType">
. Это работает независимо от того, определил я xmlns или нет. Это может быть согласовано с этим ответом , но я до сих пор не понимаю, как я мог бы реально объявить префикс в служебном коде.
@ Крис, конечно. Надеюсь, я смогу найти баланс между «скупым с закрытым исходным кодом» и «пригодным для тех, кто поможет». Здесь "books" - это XmlNode, полученный в параметре метода сервиса. (Не выходить за рамки темы, но также смиренно приму предложения по ее улучшению в целом; я все еще новичок.)
XmlSerializer xmlSerializer = new XmlSerializer(typeof(booksType));
StringReader xmlDataReader = new StringReader(books.OuterXml);
books = (booksType)xmlSerializer.Deserialize(xmlDataReader);
Класс в значительной степени такой:
[Serializable()]
[XmlRoot("books", Namespace = "namespace")]
[XmlTypeAttribute(TypeName = "booksType", Namespace = "namespace")]
public class booksType
{
[XmlElement(ElementName = "bookID")]
public string[] bookIDs { get; set; }
}