Jak usunąć deserializację tego dokumentu XML:
<?xml version="1.0" encoding="utf-8"?>
<Cars>
<Car>
<StockNumber>1020</StockNumber>
<Make>Nissan</Make>
<Model>Sentra</Model>
</Car>
<Car>
<StockNumber>1010</StockNumber>
<Make>Toyota</Make>
<Model>Corolla</Model>
</Car>
<Car>
<StockNumber>1111</StockNumber>
<Make>Honda</Make>
<Model>Accord</Model>
</Car>
</Cars>
Mam to:
[Serializable()]
public class Car
{
[System.Xml.Serialization.XmlElementAttribute("StockNumber")]
public string StockNumber{ get; set; }
[System.Xml.Serialization.XmlElementAttribute("Make")]
public string Make{ get; set; }
[System.Xml.Serialization.XmlElementAttribute("Model")]
public string Model{ get; set; }
}
.
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)]
public class Cars
{
[XmlArrayItem(typeof(Car))]
public Car[] Car { get; set; }
}
.
public class CarSerializer
{
public Cars Deserialize()
{
Cars[] cars = null;
string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data/") + "cars.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Cars[]));
StreamReader reader = new StreamReader(path);
reader.ReadToEnd();
cars = (Cars[])serializer.Deserialize(reader);
reader.Close();
return cars;
}
}
które nie działają :-(
Odpowiedzi:
Oto działająca wersja. Zmieniłem
XmlElementAttribute
etykiety na,XmlElement
ponieważ w xml wartości StockNumber, Make i Model są elementami, a nie atrybutami. Usunąłem równieżreader.ReadToEnd();
(ta funkcja odczytuje cały strumień i zwraca ciąg znaków, więcDeserialize()
funkcja nie mogła już korzystać z czytnika ... pozycja była na końcu strumienia). Wziąłem też kilka swobód z nazywaniem :).Oto zajęcia:
Funkcja deserializacji:
I nieco poprawiony plik XML (musiałem dodać nowy element do zawijania <Cars> ... Net jest wybredny w zakresie deserializacji tablic):
źródło
[Serializable]
Jest zbędny w przypadku korzystaniaXmlSerializer
;XmlSerializer
po prostu nigdy tego nie sprawdza. Podobnie większość[Xml...]
atrybutów jest zbędna, ponieważ po prostu naśladuje zachowanie domyślne; tzn. domyślnie właściwość o nazwieStockNumber
jest przechowywana jako element o nazwie<StockNumber>
- nie ma potrzeby do tego atrybutów.A może po prostu zapisz plik xml w pliku i użyj xsd do wygenerowania klas C #?
xsd foo.xml
xsd foo.xsd /classes
Et voila - i plik kodu C #, który powinien być w stanie odczytać dane poprzez
XmlSerializer
:(dołącz wygenerowany plik foo.cs do projektu)
źródło
Masz dwie możliwości.
Metoda 1. Narzędzie XSD
Załóżmy, że masz plik XML w tej lokalizacji
C:\path\to\xml\file.xml
Możesz go znaleźć w
Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
Lub jeśli masz system Windows 8, możesz po prostu zacząć pisać wiersz polecenia programisty na ekranie Startcd /D "C:\path\to\xml"
xsd file.xml
xsd /c file.xsd
I to wszystko! Wygenerowałeś klasy C # z pliku xml w
C:\path\to\xml\file.cs
Metoda 2 - Wklej specjalnie
Wymagane Visual Studio 2012+
Edit > Paste special > Paste XML As Classes
I to wszystko!
Stosowanie
Użycie tej klasy pomocniczej jest bardzo proste:
Wszystko, co musisz teraz zrobić, to:
źródło
Paste XML As Classes
polecenie jest skierowane tylko do .NET 4.5Poniższy fragment kodu powinien załatwić sprawę (możesz zignorować większość atrybutów serializacji):
...
źródło
Sprawdź, czy to pomoże:
.
W przeciwnym razie korzysta z programu xsd.exe, który jest dołączony do programu Visual Studio, aby utworzyć dokument schematu na podstawie tego pliku xml, a następnie użyć go ponownie, aby utworzyć klasę na podstawie dokumentu schematu.
źródło
Nie sądzę, że .net jest „wybredny w deserializacji tablic”. Pierwszy dokument XML nie jest poprawnie sformułowany. Nie ma elementu głównego, chociaż wygląda na to, że istnieje. Kanoniczny dokument xml ma katalog główny i co najmniej 1 element (jeśli w ogóle). W twoim przykładzie:
źródło
wypróbuj ten blok kodu, jeśli plik .xml został wygenerowany gdzieś na dysku i jeśli użyłeś
List<T>
:Uwaga:
C:\serialize.xml
to ścieżka do mojego pliku .xml. Możesz to zmienić według własnych potrzeb.źródło
Anser Kevina jest dobry, poza tym, że w prawdziwym świecie często nie jesteś w stanie zmienić oryginalnego XML, aby dopasować go do swoich potrzeb.
Istnieje również proste rozwiązanie dla oryginalnego XML:
A potem możesz po prostu zadzwonić:
źródło
Wypróbuj tę klasę ogólną do serializacji i deserializacji Xml.
źródło
Dla początkujących
Uznałem, że odpowiedzi tutaj są bardzo pomocne, ponieważ powiedziałem, że wciąż walczyłem (tylko trochę), aby to zadziałało. Na wypadek, gdyby to pomogło komuś, przeliteruję działające rozwiązanie:
XML z oryginalnego pytania. Plik xml znajduje się w pliku Class1.xml, a
path
do tego pliku użyto w kodzie, aby zlokalizować ten plik xml.Użyłem odpowiedzi @erymski, aby to zadziałało, więc utworzyłem plik o nazwie Car.cs i dodałem:
Drugi fragment kodu dostarczony przez @erymski ...
... przechodzi do twojego programu głównego (Program.cs), w
static CarCollection XCar()
następujący sposób:Mam nadzieję, że to pomoże :-)
źródło
Co powiesz na ogólną klasę do deserializacji dokumentu XML
Ta część może być lub może nie być konieczna. Otwórz dokument XML w Visual Studio, kliknij XML prawym przyciskiem myszy, wybierz właściwości. Następnie wybierz plik schematu.
źródło
Jedna wkładka:
źródło
Chodzi o to, aby wszystkie poziomy były obsługiwane dla deserializacji. Zobacz przykładowe rozwiązanie, które rozwiązało mój podobny problem
Powyższy XML jest obsługiwany na dwóch poziomach
Poziom wewnętrzny
Taki sam sposób, w jaki potrzebujesz wielu poziomów z
car as array
Sprawdź ten przykład dla deserializacji wielopoziomowejźródło
Jeśli otrzymujesz błędy przy użyciu xsd.exe do utworzenia pliku xsd, użyj klasy XmlSchemaInference, jak wspomniano w msdn . Oto test jednostkowy w celu wykazania:
źródło
Możesz po prostu zmienić jeden atrybut właściwości samochodu Cars z XmlArrayItem na XmlElment. To znaczy, z
do
źródło
Moje rozwiązanie:
Edit > Past Special > Paste XML As Classes
aby uzyskać klasę w kodzieList<class1
>), a następnie użyjXmlSerializer
do serializacji tej listy doxml
pliku.deserialize
.Kod:
UWAGA: musisz zwrócić uwagę na nazwę katalogu głównego, nie zmieniaj jej. Mój jest „ArrayOfClass1”
źródło
źródło