locked
XML issue, one unedeed line. RRS feed

  • Question

  • User-2146352328 posted

    Hi.
    I have these classes:

    <DataContract(), XmlSerializerFormat()>
    <Serializable()>
    <XmlRoot("ParamList")>
    Public Class ParamList
        Public Property ParamItem As New List(Of ParamItem)
    End Class
    
    <DataContract(), XmlSerializerFormat()>
    <Serializable()>
    <XmlRoot("ParamItem")>
    Public Class ParamItem
        Public Property Code As String
        Public Property Desc As String
    End Class

    This will produce this XML:

    <ParamList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <ParamItem>
    
    <ParamItem>
    <Code>00</Code>
    <Desc>AA</Desc>
    </ParamItem>
    
    <ParamItem>
    <Code>00</Code>
    <Desc>AA</Desc>
    </ParamItem>
    
    </ParamItem>
    </ParamList>

    So I get an extra external param item.

    what i need is this:

    <ParamList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
    <ParamItem>
    <Code>00</Code>
    <Desc>AA</Desc>
    </ParamItem>
    
    <ParamItem>
    <Code>00</Code>
    <Desc>AA</Desc>
    </ParamItem>
    
    ...etc
    
    </ParamList>

    Thanks.

    Wednesday, February 8, 2017 10:22 PM

Answers

  • User-1509636757 posted

    To disable rendering of root element of collection ParamList, you must attribute it with <XmlElement> in your code.

    <DataContract(), XmlSerializerFormat()>
    <Serializable()>
    <XmlRoot("ParamList")>
    Public Class ParamList
    <XmlElement> Public Property ParamItem As New List(Of ParamItem) End Class <DataContract(), XmlSerializerFormat()> <Serializable()> <XmlRoot("ParamItem")> Public Class ParamItem Public Property Code As String Public Property Desc As String End Class
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, February 9, 2017 6:12 PM

All replies

  • User-1509636757 posted

    To disable rendering of root element of collection ParamList, you must attribute it with <XmlElement> in your code.

    <DataContract(), XmlSerializerFormat()>
    <Serializable()>
    <XmlRoot("ParamList")>
    Public Class ParamList
    <XmlElement> Public Property ParamItem As New List(Of ParamItem) End Class <DataContract(), XmlSerializerFormat()> <Serializable()> <XmlRoot("ParamItem")> Public Class ParamItem Public Property Code As String Public Property Desc As String End Class
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, February 9, 2017 6:12 PM
  • User-2146352328 posted

    Perfect!

    Thanks.

    Friday, February 10, 2017 8:06 AM
  • User-2146352328 posted

    OK.
    One more thing for future reference.
    Using this:

    <DataContract(), XmlSerializerFormat()>
    <Serializable()>
    <XmlRoot("Coupons")>
    Public Class CouponL
        <XmlElement()>
        Public Property Coupon As New List(Of Coupon)
    End Class
    
    
    <DataContract(), XmlSerializerFormat()>
    <Serializable()>
    <XmlRoot("Coupon")>
    Public Class Coupon   
        <XmlAttribute("Id")> Public Property coupon As String  
        Public Property PerformanceId As String  
        Public Property UseTime As String   
        Public Property CinemaId As String
    End Class

    I get

    <Coupons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Coupon Id="xxx">
    <PerformanceId>3</PerformanceId>
    <UseTime>07/02/2017 06:42:56</UseTime>
    <CinemaId>xx</CinemaId>
    </Coupon>
    </Coupons>

    Is there a way to remove the coupons element?
    so it can be like this:

    <Coupon Id="xxx">
    <PerformanceId>3</PerformanceId>
    <UseTime>07/02/2017 06:42:56</UseTime>
    <CinemaId>xx</CinemaId>
    </Coupon>
    
    <Coupon Id="xxx">
    <PerformanceId>3</PerformanceId>
    <UseTime>07/02/2017 06:42:56</UseTime>
    <CinemaId>xx</CinemaId>
    </Coupon>
    
    .....etc

    I'm not sure how to do this as these must be on a list so an exoteric element will be present.
    Thanks.

    Friday, February 10, 2017 10:06 AM
  • User-1509636757 posted

    All XmlNodes must belong to a document. And an XML document must have a root node. But, you can manipulate the result with XElement.XPathSelectElements() to get only inner nodes by removing root nodes. However, you cannot then again parse or use that string as a pure Xml variable or Xml document, since it will result you in giving error "Multiple root elements found or Root element missing", as I said this is because every Xml document expected to have a root node.

    Here is a sample, on how you can manipulate and get only inner node like you asked:

    Imports System.IO
    Imports System.Xml
    Imports System.Xml.Serialization
    Imports System.Xml.XPath
    
    Public Class WebForm3
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim param As New ParamList
            Dim p1 As New ParamItem()
            p1.Code = "t"
            p1.Desc = "t"
            param.ParamItem.Add(p1)
            Dim p2 As New ParamItem()
            p2.Code = "t"
            p2.Desc = "t"
            param.ParamItem.Add(p2)
    
            Dim xsSubmit As New XmlSerializer(GetType(ParamList))
    
            Dim xml = ""
    
            Using sww = New StringWriter()
                Using writer As XmlWriter = XmlWriter.Create(sww)
                    xsSubmit.Serialize(writer, param)
                    ' Your XML
                    xml = sww.ToString()
                End Using
            End Using
    
            'This will remove root node
            Dim xmlResult As String = String.Concat(XElement.Parse(xml).XPathSelectElements("/").Nodes)
    
        End Sub
    
    End Class

    Friday, February 10, 2017 10:51 AM
  • User-2146352328 posted

    Hi.

    So the only way is to remove it by sting?

    BTW I get Error    1    'XPathSelectElements' is not a member of 'System.Xml.Linq.XElement'.     I have vs2010

    I was thinking on trying on the <XmlRoot("ParamItem")> element. I has trying to use and empty on like so:  <XmlRoot("")> but is either putting the default(something like "xs_2000", or something, or Is naming it after the Class.

    Meaning I wouldn't mind a no named XMLROOT like so:

    <xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    .
    .
    .
    </>

    Friday, February 10, 2017 11:27 AM
  • User-1509636757 posted

    BTW I get Error    1    'XPathSelectElements' is not a member of 'System.Xml.Linq.XElement'.     I have vs2010

    Add this using statement like I did

    Imports System.Xml.XPath

    Friday, February 10, 2017 11:54 AM
  • User-2146352328 posted

    OK.

    Yes but as you said it would be unreadable afterwards so I am try just to have an empty XML root.

    Can find something yet but I can just remove the name before I serialize it I guess (not the whole line)

    Friday, February 10, 2017 12:06 PM