XML limpo com XmlSerializer
Serializar um objeto com XmlSerializer... Bom, em poucas palavras, serializar é converter um objeto para um determinado formato que facilite a transmissão ou o armazenamento do mesmo. E como o próprio nome diz, XmlSerializer converte para XML.
Mas por um acaso você quer que a serialização seja sem os "xmlns:xsd=..." e sem os "xmlns:xsi=..." e sem a tradicional linha inicial "<?xml version=...", ou seja, você quer um XML limpo sem namespaces, sem atributos adicionais além dos dados do objeto que você especificou como atributo.
É... Bem que podia ter alguma coisa do tipo
serializador.Namespaces = False
ou
serializador.XmlLimpo = True
Sei lá! Algo fácil!
Mas como não tem, para de chorar e vamos programar!
Claro que não existe uma maneira apenas de fazer isso, e essa multiplicidade de soluções desse nosso mundo já está registrada no ditado 25, talvez tenha alguém que conheça outra bem mais simples... Neste caso peço que comente este post. Mas juro; aqui registro a que considerei melhor.
Herde a classe XmlTextWriter e faça o seguinte:
Public Class XmlLimpoTextWriter
Inherits System.Xml.XmlTextWriter
Private _escreverAtributo As Boolean = True
Public Sub New(ByVal writer As System.IO.TextWriter)
MyBase.New(writer)
End Sub
Public Overloads Overrides Sub WriteStartElement(ByVal prefix As String, ByVal localName As String, ByVal ns As String)
MyBase.WriteStartElement(Nothing, localName, Nothing)
End Sub
Public Overloads Overrides Sub WriteStartAttribute(ByVal prefix As String, ByVal localName As String, ByVal ns As String)
'Se o prefix ou localname forem "xmlns" não escreve...
If String.Compare(prefix, "xmlns") = 0 OrElse _
String.Compare(localName, "xmlns") = 0 OrElse _
String.Compare(localName, "nil") = 0 Then
_escreverAtributo = False
Else
MyBase.WriteStartAttribute(Nothing, localName, Nothing)
End If
End Sub
Public Overrides Sub WriteString(ByVal text As String)
'Aqui ocorre a escrita propriamente dita.
If _escreverAtributo Then
MyBase.WriteString(text)
End If
End Sub
Public Overrides Sub WriteEndAttribute()
'Se não escreveu o início do atributo não vai escrever o fim também.
If _escreverAtributo Then
MyBase.WriteEndAttribute()
End If
'Prepara variável para próximo atributo.
_escreverAtributo = True
End Sub
Public Overrides Sub WriteQualifiedName(ByVal localName As String, ByVal ns As String)
MyBase.WriteQualifiedName(localName, Nothing)
End Sub
Public Overloads Overrides Sub WriteStartDocument()
'Aqui eu tiro a primeira linha do xml não fazendo nada.
'<?xml version="1.0" encoding="utf-8" ?>
End Sub
End Class
Agora vamos fazer um teste. Crie a classe Produto (Sei que não criei as propriedades, isso aqui é só um exemplo! Não adianta brigar comigo!):
Public Class Produto
Public Codigo As String
Public Nome As String
Public Quantidade As Integer
End Class
Agora vamos usar isso tudo ai:
Private Sub SerializaObjeto()
Dim objetos(1) As Produto
Dim texto As New System.Text.StringBuilder
Dim serializador As New System.Xml.Serialization.XmlSerializer(GetType(Produto()), _
New System.Xml.Serialization.XmlRootAttribute("Produtos"))
Dim escritorTexto As New System.IO.StringWriter(texto)
'Descomente um e comente o outro só pra testar e ver as diferenças
Dim escritorXml As New XmlLimpoTextWriter(escritorTexto)
'Dim escritorXml As New System.Xml.XmlTextWriter(escritorTexto)
'Gerar um xml bonitinho....
escritorXml.Formatting = Xml.Formatting.Indented
'Testando....
Dim objeto1 As New Produto
objeto1.Codigo = 1
objeto1.Nome = "Produto"
objeto1.Quantidade = 5
Dim objeto2 As New Produto
objeto2.Codigo = 2
objeto2.Nome = "Produto1"
objeto2.Quantidade = 10
'Joga no array
objetos(0) = objeto1
objetos(1) = objeto2
'Serializa(Converte pra xml)
serializador.Serialize(escritorXml, objetos)
escritorXml.Flush()
escritorXml.Close()
escritorTexto.Close()
'Exibe o resultado
MessageBox.Show(texto.ToString)
End Sub
Olha o que saiu:
<Produtos>
<Produto>
<Codigo>1</Codigo>
<Nome>Produto</Nome>
<Quantidade>5</Quantidade>
</Produto>
<Produto>
<Codigo>2</Codigo>
<Nome>Produto1</Nome>
<Quantidade>10</Quantidade>
</Produto>
</Produtos>
Limpinho!
Essa tal de programação quando funciona é bom demais heim? Fala sério!
Se tiver alguma surpresa, algum outro atributo indesejado..., só colocar ele lá no método WriteStartAttribute() que o bendito não lhe incomodará novamente.
Abraço!
//Cleydson
Assunto: Removing xmlns, removendo xmlns, remove namespaces