none
Beim Deserialize fehlende Namespace zufügen RRS feed

  • Frage

  • Hallo NG,

    Ich erstelle extern ein Telefonbuch für die Fritzbox 7270. Die XML-Datei hat folgende 1. Zeilen:

    <?xml version="1.0"?>
    <phonebooks xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.cpandl.com">
      <phonebook name="Telefonbuch" nid="164">
        <contact>
    

    Das Einlesen in die Fritzbox funktioniert einwandfrei, obgleich die originale Struktur etwas abweicht. Auch die Daten werden im Telefonbuch korrekt dargestellt und verarbeitet. Beim Sichern des Telefonbuches aus der Fritzbox werden alle Daten korrekt exportiert. Nur die ersten Zeilen nicht.

    <?xml version="1.0" encoding="utf-8"?> <phonebooks> <phonebook name="Telefonbuch" nid="164">

    Nach dem Aufruf von:

    XmlSerializer serializer = new XmlSerializer(typeof(Phonebooks));
    

    sind folgende Namespaces in serializer enthalten

    Es kommt zu einem Fehler beim Einlesen

    Auch wenn ich folgenden Befehl verwende

    XmlSerializer serializer = new XmlSerializer(typeof(Phonebooks),"http://www.cpandl.com");

    funktioniert es nicht.

    Wenn ich dagegen manuell in die XML diese Zeile dahingend ändere

    <phonebooks xmlns="http://www.cpandl.com">

    funktioniert das Einlesen.

    Kann ich diese fehlende Namespace noch irgend wie anders hinzufügen?

    Vielen Dank Klaus

    Freitag, 20. November 2015 11:16

Antworten

  • Hallo Klaus,

    es wäre hilfreich, wenn Du uns den Fehler (bitte die genaue und vollständige Meldung) verraten würdest.

    Behelfsweise kannst Du natürlich auch einfach den XML String, den Du ja wahrscheinlich hast, vor der Übergabe den die Deserialisierungsmethode per Replace anpassen. Dazu solltest Du die Datei bspw. per File.ReadAllText einlesen und dann per:

    xmlContent = xmlContent.Replace( "<phonebooks>", "<phonebooks xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.cpandl.com\">" );
    

    ersetzen. Die Deserialisierung kann dann direkt über den String erfolgen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Freitag, 20. November 2015 14:07
    Moderator
  • Hi Klaus,
    die FritzBox ignoriert den Namensraum. Deine Klasse ist aber so gestaltetet, dass sie einen Namensraum beim Einlesen benötigt. Diesen Namensraum liefert die FritzBox aber nicht. Da bleibt Dir nur, die Klasse ohne Namensraum zu deklarieren und beim Serialisieren den Namensraum als 3. Parameter anzugeben.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Freitag, 20. November 2015 15:28
  • Hi Klaus,
    hier mal ein Beispiel in VB.NET. In der Klasse Phonebooks ist das XmlRoot auskommentiert.

    Imports System.IO
    Imports System.Xml.Serialization
    
    Module Module12
      Sub Main()
        Dim pb As New Phonebooks With {.Name = "Name"}
        Dim serializer As New XmlSerializer(GetType(Phonebooks))
        Dim ns As New XmlSerializerNamespaces()
        ns.Add("", "http://www.cpandl.com")
        Using fs As New FileStream("c:\temp\x.xml", FileMode.Create)
          serializer.Serialize(fs, pb, ns)
        End Using
        Using fs As New FileStream("c:\temp\x.xml", FileMode.Open)
          pb = CType(serializer.Deserialize(fs), Phonebooks)
        End Using
    
    
    
        Console.Write("beenden mit beliebiger Taste")
        Console.ReadKey()
      End Sub
    End Module
    
    '<XmlRoot("Node", Namespace:="http://www.cpandl.com")>
    
    Public Class Phonebooks
      Public Property Name As String
    End Class


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Freitag, 20. November 2015 15:42

Alle Antworten

  • Hallo Klaus,

    lege für Deine Phonebooks Klasse den Root-Namespace via XmlRoot-Attribut fest, siehe dazu:

    XML Serialization and namespace prefixes

    Gruß Elmar

    Freitag, 20. November 2015 11:26
    Beantworter
  • Hallo Elmar,

    ich habe es wohl nicht richtig rüber gebracht. Das was du vorschlägst habe ich natürlich gemacht. Das Einlesen der von meinem Programm per

    XmlSerializer serializer = new XmlSerializer(typeof(Phonebooks));

    funktioniert ja auch einwandfrei. Nur die Fritzbox verschluckt leider die Namespace beim Export. Da ich aber auch hier Einträge pflege, möchte ich diese Datei natürlich auch verwenden können.

    Gruß Klaus

    Freitag, 20. November 2015 11:39
  • Hi Klaus,
    wenn Du beim Einlesen auf einen Namensraum verzichtest, kannst Du doch alles einlesen. Wo ist dann das Problem?

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Freitag, 20. November 2015 12:19
  • Hallo Peter,

    aber das ist ja das Problem. In der Klasse ist der Namespace ja fix definiert sonst würde ja das Searialisen nicht funktionieren. Dadurch werden die Namespaces ja auch in die XKL-Datei geschrieben, und sie können problemlos deserialisiert werden.

    Aber wenn die Fritzbox die XML-Datei mit den selben Daten erstellt, fehlen diese Namespaces und die Deserialisierung schlägt fehlt!!

    Gruß Klaus

    Freitag, 20. November 2015 12:45
  • Hallo Klaus,

    es wäre hilfreich, wenn Du uns den Fehler (bitte die genaue und vollständige Meldung) verraten würdest.

    Behelfsweise kannst Du natürlich auch einfach den XML String, den Du ja wahrscheinlich hast, vor der Übergabe den die Deserialisierungsmethode per Replace anpassen. Dazu solltest Du die Datei bspw. per File.ReadAllText einlesen und dann per:

    xmlContent = xmlContent.Replace( "<phonebooks>", "<phonebooks xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.cpandl.com\">" );
    

    ersetzen. Die Deserialisierung kann dann direkt über den String erfolgen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Freitag, 20. November 2015 14:07
    Moderator
  • Hi Klaus,
    die FritzBox ignoriert den Namensraum. Deine Klasse ist aber so gestaltetet, dass sie einen Namensraum beim Einlesen benötigt. Diesen Namensraum liefert die FritzBox aber nicht. Da bleibt Dir nur, die Klasse ohne Namensraum zu deklarieren und beim Serialisieren den Namensraum als 3. Parameter anzugeben.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Freitag, 20. November 2015 15:28
  • Hallo Peter,

    habe ich soweit verstanden, allerdings wäre ich für ein Beispiel, wie das umzusetzen ist, dankbar.

    Gruß Klaus

    Freitag, 20. November 2015 15:32
  • Hi Klaus,
    hier mal ein Beispiel in VB.NET. In der Klasse Phonebooks ist das XmlRoot auskommentiert.

    Imports System.IO
    Imports System.Xml.Serialization
    
    Module Module12
      Sub Main()
        Dim pb As New Phonebooks With {.Name = "Name"}
        Dim serializer As New XmlSerializer(GetType(Phonebooks))
        Dim ns As New XmlSerializerNamespaces()
        ns.Add("", "http://www.cpandl.com")
        Using fs As New FileStream("c:\temp\x.xml", FileMode.Create)
          serializer.Serialize(fs, pb, ns)
        End Using
        Using fs As New FileStream("c:\temp\x.xml", FileMode.Open)
          pb = CType(serializer.Deserialize(fs), Phonebooks)
        End Using
    
    
    
        Console.Write("beenden mit beliebiger Taste")
        Console.ReadKey()
      End Sub
    End Module
    
    '<XmlRoot("Node", Namespace:="http://www.cpandl.com")>
    
    Public Class Phonebooks
      Public Property Name As String
    End Class


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Freitag, 20. November 2015 15:42
  • Hallo Elmar, Peter, Stephan,

    viele Dank für Eure Bemühungen.

    Nach dem Code-Beispiel von Peter habe ich mich noch einmal intensiv mit dem Thema auseinandergesetzt und bin zu folgendem überraschenden Ergebnis gekommen:

    In dieser Zeile der Class Phonbooks den Verweis auf die Namespace einfach weglassen dann funktioniert alles ohne new XmlSerializeNamespaces.

     [XmlRootAttribute("phonebooks" Namespace = "http://www.cpandl.com", IsNullable = false)]

    Gruß Klaus



    Montag, 23. November 2015 10:47