Kevin Henzel Kevin Henzel - 1 month ago 23
Vb.net Question

How do i build namespaces xmlns, xmlns:xsi, and schema xsi:schemalocaton in my XML via VB.net?

I need to replicate a xml header:

<XDataFeed
xmlns="http://foo.com/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" .
xsi:schemaLocation="http://foo.com/namespace C:\fooXSD.XML">


with my code:

'Export the object to XML
Dim writer As New XmlSerializer(DataFeed.GetType)
Dim ns As New XmlSerializerNamespaces()
ns.Add("xmlns", "http://foo.com/namespace")
ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance")
Dim file As New System.IO.StreamWriter("C:\foo.xml")
writer.Serialize(file, DataFeed, ns)
file.Close()


and i'm hitting 2 issues:


  1. when i try to add my namespace without a prefix for foo.com, it removes all namespaces. My code above adds foo.com's namespace as:

    xmlns:xmlns="http://foo.com/namespace"



which is not correct. How do i simply add in the namespace without a prefix?


  1. i have searched for an hour trying to figure out how to append the attribute "xsi:schemaLocation..." to my xml, though every single example i found uses types in c#, or manipulation to a declared xml doc which are not aplicable to my VB.Net XmlSerializer approach. How do i go about appending the schemaLocation attribute to my xml by way of the XmlSerializer code above?



I greatly appreciate the assistance. I need to get my XML to pass through via XSD validation to be approved, and this is the final piece that is standing in my way.

Answer

Just had to do this myself.

Don't add your namespace into the XmlSerializerNamespaces. Instead, just put it on your parent object. This should make it not have a prefix and just be xmlns="http://...".

<XmlRoot(Namespace:="http://foo.com/namespace")>
Public Class XDataFeed
    '...
End Class

If for some reason it slaps in a dummy prefix like d1p1, use string.Empty for your prefix and go ahead and add your namespace to the XmlSerializerNamespaces.

In order for the SchemaLocation to show up, you can create a dummy property and tag it up accordingly:

<XmlAttribute("schemaLocation", NameSpace:=XmlSchema.InstanceNamespace)>
Public Property SchemaLocation As String
    Get
        Return "http://foo.com/namespace C:\fooXSD.XML"
    End Get
    Set(value As String)
        'Ignore... pureley needed for serialization.
    End Set
End Property

You are already adding in the xsi namespace so it should work just fine if you keep doing that. Just take out your xmlns namespace.

In the end you should end up with a class like this:

<XmlRoot(Namespace:="http://foo.com/namespace")>
Public Class XDataFeed

    <XmlAttribute("schemaLocation", NameSpace:=XmlSchema.InstanceNamespace)>
    Public Property SchemaLocation As String
        Get
            Return "http://foo.com/namespace C:\fooXSD.XML"
        End Get
        Set(value As String)
            'Ignore... pureley needed for serialization.
        End Set
    End Property

End Class
Comments