I got thousands of XML files following all the same schema/structure. I implemented IXmlSerializable and thus am reading the elements and attributes myself.
My problem is that these files each use a different phony namespace. These files come from an other source so I cannot change that :D Also, there are too many of those namespaces for me to just build an array of the possible namespaces and pass it along to the xmlserializer.
Right now, if I don't specify a namespace, it throws a [xmlns:ns0="http://tempuri.org/abcd.xsd" was not expected] error.
I would like to be able to tell the serializer to simply ignore the namespace when deserializing my object and just fire ReadXML. Or just be able to tell it to accept any "http://tempuri.org/" namespace.
Is that possible?
I would like to avoid modifying the files as much as possible.
Thank you!
Yes, it is possible. When you call the Deserialize
method of your XmlSerializer
, you can specify an XmlTextReader
instance.
This answer by Cheeso on a related C# question shows how to create an XmlTextReader
which ignores any namespaces occurring in the XML file. I have taken the liberty to translate his idea to VB and create a simple proof-of-concept example based on your requirements:
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Serialization
' Helper class
Class NamespaceIgnorantXmlTextReader
Inherits XmlTextReader
Public Sub New(stream As Stream)
MyBase.New(stream)
End Sub
Public Overrides ReadOnly Property NamespaceURI As String
Get
Return ""
End Get
End Property
End Class
' Serializable class
Public Class ExampleClass
Public Property MyProperty As String
End Class
' Example
Module Module1
Sub Main()
Dim testXmlStream = New MemoryStream(Encoding.UTF8.GetBytes(
"<ExampleClass xmlns=""http://tempuri.org/SomePhonyNamespace1.xsd""
xmlns:ph2=""http://tempuri.org/SomePhonyNamespace2.xsd"">
<ph2:MyProperty>SomeValue</ph2:MyProperty>
</ExampleClass>"))
Dim serializer As New XmlSerializer(GetType(ExampleClass))
Dim reader As New NamespaceIgnorantXmlTextReader(testXmlStream)
Dim example = DirectCast(serializer.Deserialize(reader), ExampleClass)
Console.WriteLine(example.MyProperty) ' prints SomeValue
End Sub
End Module
Note: If it's just the document's default namespace which is different (i.e., the individual tags don't have different namespaces), using a standard TextXmlReader
with the Namespaces
property set to False
suffices.
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Serialization
' Serializable Class
Public Class ExampleClass
Public Property MyProperty As String
End Class
' Example
Module Module1
Sub Main()
Dim testXmlStream = New MemoryStream(Encoding.UTF8.GetBytes(
"<ExampleClass xmlns=""http://tempuri.org/SomePhonyNamespace1.xsd"">
<MyProperty>SomeValue</MyProperty>
</ExampleClass>"))
Dim serializer As New XmlSerializer(GetType(ExampleClass))
Dim reader As New XmlTextReader(testXmlStream)
reader.Namespaces = False
Dim example = DirectCast(serializer.Deserialize(reader), ExampleClass)
Console.WriteLine(example.MyProperty) ' prints SomeValue
End Sub
End Module
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With