#c# #xml #serialization
#c# #xml #сериализация
Вопрос:
Я извлекаю XML-документы из веб-службы, которую я не контролирую. XML форматируется аналогично следующему:
<?xml version="1.0"?>
<ns:obj xmlns:ns="somenamespace">
<address>1313 Mockingbird Lane</address>
<residents>5</residents>
</ns:obj>
где корневой узел находится в пространстве имен «ns», но ни один из его дочерних элементов.
После некоторых проб и ошибок я обнаружил, что могу десериализовать документ в объект C #, выполнив следующее:
[XmlRoot(Namespace="somenamespace", ElementName="obj")]
public class xmlObject
{
[XmlElement(Namespace = "")]
public string address { get; set; }
[XmlElement(Namespace = "")]
public int residents { get; set; }
}
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version="1.0"?>"
"<ns:obj xmlns:ns="somenamespace">"
" <address>1313 Mockingbird Lane</address>"
" <residents>5</residents>"
"</ns:obj>";
var serializer = new XmlSerializer(typeof(xmlObject));
using (var reader = new StringReader(xml))
{
var result = serializer.Deserialize(reader) as xmlObject;
Console.WriteLine("{0} people live at {1}", result.residents, result.address);
// Output: "5 people live at 1313 Mockingbird lane"
}
}
}
Если я опущу XmlElementAttribute
on отдельных членов, я вместо этого получу пустой объект. Т.е. Вывод гласит
0 people live at
( result.address
равно null
.)
Я понимаю обоснование того, почему процесс десериализации работает именно так, но мне интересно, есть ли менее подробный способ сообщить XmlSerializer
, что дочерние элементы объекта не находятся в том же пространстве имен, что и корневой узел.
Объекты, с которыми я работаю в рабочей среде, имеют десятки членов, и, ради чистоты, я бы хотел избежать пометки их всех [XmlElement(Namespace = "")]
, если этого легко избежать.
Ответ №1:
Вы можете объединить XmlRootAttribute
с XmlTypeAttribute
, чтобы сделать так, чтобы корневой элемент и элементы корневого элемента имели разные пространства имен:
[XmlRoot(Namespace="somenamespace", ElementName="obj")]
[XmlType(Namespace="")]
public class xmlObject
{
public string address { get; set; }
public int residents { get; set; }
}
Используя приведенный выше тип, если я десериализую и повторно сериализую ваш XML, я получаю:
<q1:obj xmlns:q1="somenamespace"> <address>1313 Mockingbird Lane</address> <residents>5</residents> </q1:obj>
Пример скрипки.
Ответ №2:
Если вы знаете контракт с веб-службой, почему бы не использовать DataContractSerializer для десериализации XML в объекты?