#c# #vb.net #xml-serialization
#c# #vb.net #xml-сериализация
Вопрос:
У меня такой xml:
<?xml version="1.0" encoding="utf-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="blah@blah.com" start="2011-10-03T15:09:30.481Z">
<ls>
<destination value="/incoming/monthly" />
<files>
<file>
<filename value="2.txt" />
<type value="D" />
<modification value="2011-09-14T12:58:26.000Z" />
<permissions value="rwxr-xr-x" />
</file>
<file>
<filename value="3.txt" />
<type value="D" />
<modification value="2011-01-03T22:04:55.000Z" />
<permissions value="rwxr-xr-x" />
</file>
</files>
<result success="true" />
</ls>
</session>
Мое представление следующего:
<XmlRoot("session", Namespace:="http://winscp.net/schema/session/1.0")>
Class XMLSession
<XmlElement("ls/files/file")>
Public Property FileList As New List(Of XMLFile)
End Class
<XmlType("file")>
Class XMLFile
<XmlElement("filename")>
Public Property FileName As XMLValueAttribute
<XmlElement("type")>
Public Property TypeName As XMLValueAttribute
<XmlElement("permissions")>
Public Property Permissions As XMLValueAttribute
<XmlElement("modification")>
Public Property ModificationDate As XMLValueAttribute
End Class
Class XMLValueAttribute
<XmlAttribute("value")>
Public Property Value As String
End Class
Почему XMLSession.Список файлов.Считайте всегда 0. Я предполагаю, что это как-то связано с объявлением над ним, но я не уверен, что с этим не так. Возможно, он не может принять путь, если нет, как я могу это сделать?
Комментарии:
1. Исправлен ли ваш формат XML? Похоже, это может потребовать некоторой работы. Например, вместо
<file><filename value="2.txt" /></file>
, что-то вроде<file filename="2.txt" />
имело бы больше смысла — похоже, что все ваши подэлементы имеют только одно значение. Если бы вы внесли это изменение, ваша сериализация также была бы намного проще.2. Этот формат генерируется WinSCP, поэтому я не могу его контролировать
Ответ №1:
Вы не можете описать несколько уровней XML с помощью одного атрибута XmlElementAttribute. Вам нужны классы для каждого уровня.
Комментарии:
1. Есть ли способ избежать наличия классов для каждого из них?
2. @marc_s: Ваш комментарий не совсем верен. Вам не нужен класс для «файлов», например, если вы используете <XMLArray(«files»)> . Теперь, если бы мне не нужен был класс для «Ls»
Ответ №2:
Если вы не хотите создавать классы вручную, вы можете получить инструменты, которые сделают это за вас:
Предполагая, что ваш XML сохранен в data.xml
:
xsd.exe data.xml
Это даст вам data.xsd
определение XML.
xsd.exe /l:VB /n:SomeNamespace /c data.xsd
Это даст вам кодовый data.vb
файл с определенными вашими типами, который вы можете добавить в свой проект.
Проблема с этим заключается в том, что есть какая-то ошибка, описанная здесь, которая выдает ошибку при создании сериализатора вокруг этого нового типа. Итак, вам просто нужна одна ручная настройка сгенерированного кода, изменение:
<XmlArrayItemAttribute("file", GetType(sessionLSFilesFile), IsNullable:=False)> _
'To
<XmlArrayItemAttribute("file", GetType(sessionLSFilesFile()), IsNullable:=False)> _
Комментарии:
1. жаль, что я не знал об этом до того, как начал 😉 Спасибо
2. @Denis: все это есть в документации.