Member 11403304 Ответов: 5

Как создать XML-документации в VB.NET


Я хотел бы создать следующий xml-документ в vb.net
Как мне это сделать?

<?xml version="1.0" encoding="UTF-8"?>
<MyMessage>
   <Request>
	<User>
	  <PersonName>
	     <Name>My Username</Name>
	  </PersonName>
        </User>
   </Request>
   <CarVin>1234566</CarVin>
</MyMessage>


Что я уже пробовал:

Я не знаю, как это сделать. Пожалуйста помочь

5 Ответов

Рейтинг:
5

Lockwood

Бросаю еще одну шляпу на ринг

Dim xdoc = New XDocument(
    New XElement("MyMessage",
        New XElement("Request",
            New XElement("User",
                New XElement("PersonName",
                    New XElement("Name","My Username")))),
        New XElement("CarVin","1234566")))
xdoc.Save(AppDomain.CurrentDomain.BaseDirectory & "\file.xml")


Не самый полезный код в мире в этом формате, но вы можете использовать его в качестве основы для получения чего-то более подходящего для ваших нужд.


Рейтинг:
43

Graeme_Grant

Существует множество различных способов в зависимости от того, как работает ваше приложение.

Один из методов состоит в том, чтобы иметь класс, получить свойства, а затем сериализовать & десериализовать в/из XML.

Итак, вот представление класса вашего XML:

Public Class PersonName

    Public Property Name() As String

End Class

Public Class User

    Public Property PersonName() As PersonName

End Class

Public Class Request

    Public Property User() As User

End Class

<XmlRoot(ElementName:="MyMessage")>
Public Class MyMessage

    Public Property Request() As Request

    Public Property CarVin() As String

End Class

Далее нам нужно обернуть код сериализации в вспомогательный класс. Это то, что мы используем в нашем коммерческом программном обеспечении (преобразованном в VB):
Imports System.Xml.Serialization
Imports System.Xml
Imports System.IO
Imports System.Text

Public NotInheritable Class XmlHelper
    Private Sub New()
    End Sub
    Public Shared Function FromClass(Of T)(data As T, _
                      Optional ns As XmlSerializerNamespaces = Nothing) As String
        Dim response As String = String.Empty

        Dim ms = New MemoryStream()
        Try
            ms = FromClassToStream(data)

            If ms IsNot Nothing Then
                ms.Position = 0
                Using sr = New StreamReader(ms)
                    response = sr.ReadToEnd()
                End Using

            End If
        Finally
            ' don't want memory leaks...
            ms.Flush()
            ms.Dispose()
            ms = Nothing
        End Try

        Return response
    End Function

    Public Shared Function FromClassToStream(Of T)(data As T, _
                      Optional ns As XmlSerializerNamespaces = Nothing) As MemoryStream
        Dim stream = Nothing

        If data IsNot Nothing Then
            Dim settings = New XmlWriterSettings() With
            {
                .Encoding = Encoding.UTF8,
                .Indent = True,
                .ConformanceLevel = ConformanceLevel.Auto,
                .CheckCharacters = True,
                .OmitXmlDeclaration = False
            }

            Try
                'XmlSerializer ser = new XmlSerializer(typeof(T));
                Dim serializer As XmlSerializer = _
                    XmlSerializerFactoryNoThrow.Create(GetType(T))

                stream = New MemoryStream()
                Using writer As XmlWriter = XmlWriter.Create(stream, settings)
                    serializer.Serialize(writer, data, ns)
                    writer.Flush()
                End Using
                stream.Position = 0
            Catch ex As Exception
                stream = Nothing
#If DEBUG Then
                Debug.WriteLine(ex)
                Debugger.Break()
#End If
            End Try
        End If

        Return stream

    End Function

    Public Shared Function ToClass(Of T)(data As String) As T

        Dim response = Nothing

        If Not String.IsNullOrEmpty(data) Then
            Dim settings = New XmlReaderSettings() With
            {
                .IgnoreWhitespace = True,
                .DtdProcessing = DtdProcessing.Ignore
            }

            Try
                Dim serializer As XmlSerializer = _
                    XmlSerializerFactoryNoThrow.Create(GetType(T))

                Using sr = New StringReader(data)
                    Using reader = XmlReader.Create(sr, settings)
                        response = _
                            DirectCast(Convert.ChangeType( _
                                serializer.Deserialize(reader), GetType(T)), T)
                    End Using
                End Using
            Catch ex As Exception
#If DEBUG Then
                Debug.WriteLine(ex)
                Debugger.Break()
#End If
            End Try
        End If
        Return response

    End Function

End Class

' ref: http://stackoverflow.com/questions/1127431/xmlserializer-giving-filenotfoundexception-at-constructor/39642834#39642834
Public NotInheritable Class XmlSerializerFactoryNoThrow
    Private Sub New()
    End Sub
    Public Shared cache As New Dictionary(Of Type, XmlSerializer)()

    Private Shared SyncRootCache As New Object()

    Public Shared Function Create(type As Type) As XmlSerializer

        Dim serializer As XmlSerializer

        SyncLock SyncRootCache
            If cache.TryGetValue(type, serializer) Then
                Return serializer
            End If
        End SyncLock

        SyncLock type
            'multiple variable of type of one type is same instance
            'constructor XmlSerializer.FromTypes does not throw the first
            '     chance exception           
            'serializer = XmlSerializerFactoryNoThrow.Create(type);
            serializer = XmlSerializer.FromTypes(New Type() {type})(0)
        End SyncLock

        SyncLock SyncRootCache
            cache(type) = serializer
        End SyncLock

        Return serializer

    End Function

End Class

Теперь мы готовы сериализовать / десериализовать класс< & gt; XML:
Dim message As New MyMessage With
{
    .CarVin = "1234566",
    .Request = New Request With
    {
        .User = New User With
        {
            .PersonName = New PersonName With
            {
                .Name = "My Username"
            }
        }
    }
}

' to XML
Dim rawXmlMessage = XmlHelper.FromClass(message)
Console.WriteLine(rawXmlMessage)

' from XML
Dim newMessage = XmlHelper.ToClass(Of MyMessage)(rawXmlMessage)


Member 11403304

Большое спасибо за вашу помощь. Я использовал то, что вы дали мне в качестве примера, чтобы заставить мое решение работать. Мне приходилось обходить их стороной. Еще раз спасибо

Graeme_Grant

Добро пожаловать. :)

Вспомогательная функция немного многословна, но она извлечена и преобразована в VB из одного из моих коммерческих приложений, которое обрабатывает гораздо более сложные данные. Он должен покрывать все ваши потребности сейчас и в будущем.

Рейтинг:
32

Richard MacCutchan

Класс XmlWriter (System.Xml)[^].


Рейтинг:
28

Iris Panabaker

если вы работаете с XML, используйте эти инструменты для форматирования и проверки XML-данных.

Форматер XML
XML-валидатор


Рейтинг:
0

Patrice T

Цитата:
Я не знаю, как это сделать.

На ваш вопрос ответить невозможно. Мы не можем научить вас программированию.

Есть буквально десятки способов сделать это, и все зависит от деталей, которые Вы нам не дали.
Способ / метод использования зависит от того, откуда берутся данные, их структура, что вы хотите делать с этими данными, ваши вкусы в кодировании, используете ли вы вспомогательную библиотеку или нет.
Это может быть так же просто, как:
User= "My Username"
CarVin= "1234566"
Msg="<?xml version=""1.0"" encoding=""UTF-8""?><MyMessage><Request><User><PersonName><Name>"+User+"</Name></PersonName></User></Request><CarVin>"+CarVin+"</CarVin></MyMessage>"


Graeme_Grant

Возможно, вы захотите переосмыслить эти типы ответов и, возможно, опубликовать их в качестве комментариев вместо решений, которыми они на самом деле не являются...

Patrice T

Ну, я знаю, что у меня есть проблемы с разумными ответами на такие плохие вопросы, на которые практически невозможно ответить, потому что у нас нет контекста.

Graeme_Grant

Я могу согласиться с вами и в других случаях, но мне кажется, что здесь Вы зашли слишком далеко.

Я сделал аналогичный вступительный комментарий, однако за ним последовало одно рабочее решение... Ваше решение на самом деле не решение, а мнение, подходящее только в качестве комментария.

Patrice T

Я принимаю это к сведению на будущее.

Graeme_Grant

Извините, если я был немного резок, но чувствовал, что в этом случае я должен высказаться. Я ожидаю не меньшего от других, если поступаю так же.

Patrice T

Я все еще предпочитаю резкий комментарий, а не анонимный даунвот без комментариев.

Graeme_Grant

Как и все мы... Может быть, не самая суровая часть, но обратная связь помогает... ;)