Hallo,
ich möchte eine XML Datei in ein CSV Format wandeln.
Leider bekomme ich den Code nicht ganz hin.
Ich bekomme eine Fehlermeldung:> Fehlermeldung:
Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt
XML hat folgende Struktur:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TimeKeepingEntries xmlns="">
<entry>
<staffNumber>22</staffNumber>
<salaryTypeNumber>200</salaryTypeNumber>
<businessProcess>
<processNumber>170023</processNumber>
<processType>PROJECT</processType>
</businessProcess>
<workingPeriod>
<period>4.0</period>
<periodUnit>HOURS</periodUnit>
<beginDate>2018-01-02Z</beginDate>
<endDate>2018-01-02Z</endDate>
<timespan>
<beginTime>08:00:00Z</beginTime>
<endTime>12:00:00Z</endTime>
</timespan>
</workingPeriod>
<costUnit>170023</costUnit>
</entry>
<entry>
<staffNumber>22</staffNumber>
<salaryTypeNumber>210</salaryTypeNumber>
<businessProcess>
<processNumber>170023</processNumber>
<processType>PROJECT</processType>
</businessProcess>
<workingPeriod>
<period>10.0</period>
<periodUnit>HOURS</periodUnit>
<beginDate>2018-01-01Z</beginDate>
<endDate>2018-01-01Z</endDate>
<timespan>
<beginTime>08:00:00Z</beginTime>
<endTime>16:00:00Z</endTime>
</timespan>
</workingPeriod>
</entry>
</TimeKeepingEntries>
Code:
static void Main(string[] args)
{
XElement custOrd = XElement.Load("stunden.xml");
string csv =
(from el in custOrd.Element("TimeKeepingEntries").Elements("entry")
select
String.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}",
(string)el.Element("staffNumber"),
(string)el.Element("salaryTypeNumber"),
(string)el.Element("businessProcess").Element("processNumber"),
(string)el.Element("businessProcess").Element("processType"),
(string)el.Element("workingPeriod").Element("period"),
(string)el.Element("workingPeriod").Element("periodUnit"),
(string)el.Element("workingPeriod").Element("beginDate"),
(string)el.Element("workingPeriod").Element("endDate"),
(string)el.Element("workingPeriod").Element("timespan").Element("beginTime"),
(string)el.Element("workingPeriod").Element("timespan").Element("endTime"),
(string)el.Element("costUnit"),
Environment.NewLine
)
)
.Aggregate(
new StringBuilder(),
(sb, s) => sb.Append(s),
sb => sb.ToString()
);
Console.WriteLine(csv);
}
Dann ist etwas null.
Siehe [FAQ] NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt und [Artikel] Debugger: Wie verwende ich den von Visual Studio?
Damit findest Du den Fehler selbst; vermutlich wird ein Element nicht gefunden oder sowas.
Die korrekte Weise einen Wert zu lesen ist das Value-Property abzufragen und nicht auf einen String zu casten.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo,
danke für die Antwort.
Danach hab ich schon gesucht. Ich finde aber den Fehler nicht. Bin auch noch Anfänger auf diesem Gebiet.
Du bist Anfänger im Debuggen, wirfst aber gleich wilde Linq Statements in deinen Code die du dann nicht mehr unter Kontrolle hast? Ich würde einen Schritt nach dem anderen machen.
custOrd.Element("TimeKeepingEntries")
liefert dir
NULL
zurück.
custOrd.Elements("entry")
wäre korrekt.
Edit:
In deiner XML Struktur ist "TimeKeepingEntries" der Name und "entry" die einzelnen Elemente.
Durch das Debuggen hättest du festgestellt das der Aufruf custOrd.Element("TimeKeepingEntries") NULL zurückliefert und entsprechend der Rest dann auf eine NullReference läuft.
Wenn du dir den Aufruf
XElement custOrd = XElement.Load("stunden.xml");
Im Debugger / Watch anschaust wirst du feststellen das custOrd.Name == "TimeKeepingEntries" ist.
Developers, Developers, Developers, Developers,
Developers, Developers, Developers, Developers,
Developers, Developers, Developers, Developers ...
:evil:
Hallo,
mal abgesehen davon ist die Schreibweise eher gefährlich der nächsten 'null'-Exception nahe.
Sollte mal durch irgendwelche Umstände ein Element fehlen, dann knallts wieder.
Dabei spielt auch immer die Rolle, welche Infos sind pflicht und welche nur optional, jenachdem sollte man Fehlerbehandlungen einbauen oder einfach vorher auf 'null' prüfen...
Grüße
Ich habe den Titel mal angepasst, so dass Suchende auch etwas damit anfangen können. EDIT: Ich sollte beim Wort "Shift" im Titel das "f" nicht vergessen... 😄
Hallo RevangeXX
Ich würde auch schauen, dass du die Doppeltungen der Keys, bspw. von "workingPeriod" loswirst.
Du lädst dieses Element einmal in eine Variable und kannst dann davon Untereelemente abfragen.
Gruss Peter
--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011
Da's noch keiner erwähnt hat:
i.e.:
el?.Element("businessProcess")?.Element("processNumber")
Bei einem string.format ist zudem der cast auf string nicht nur überflüssig, sondern, da's ein "harter" cast ist, auch noch gefährlich. Dazu wäre es ein guter Gedanke, string interpolation zu nutzen.
Zu guter Letzt kann man sich angewöhnen, zu parsendes XML immer zu validieren, bevor man es parst. Entweder das, oder man prüft beim Parsen, ob alle benötigten Elemente da sind (und wenn man das macht, muss an sich fragen lassen, wieso man überhaupt XML nutzt. Validierung kommt quasi kostenlos mit XML...).
Oder man lässt den ganzen händischen Kram und serialisiert/deserialisiert. Ist auch schneller und fehlerfreier geschrieben.
LaTino
"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)