Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Wert von Knoten in XML-Datei auslesen
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

Wert von Knoten in XML-Datei auslesen

beantworten | zitieren | melden

Hallo Leute,

bekomme von einem Progamm viele automatisch erstellte xml-Dateien mit folgendem Inhalt:
 <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd">
	<CstmrCdtTrfInitn>
		<GrpHdr>
			<MsgId>108-001-20150827143657034</MsgId>
			<CreDtTm>2015-08-27T14:36:57.000Z</CreDtTm>
			<NbOfTxs>1</NbOfTxs>
			<CtrlSum>18972.43</CtrlSum>
			<InitgPty>
				<Nm>Firma</Nm>
			</InitgPty>
		</GrpHdr>
		<PmtInf>
			<PmtInfId>2015082714365703</PmtInfId>
			<PmtMtd>TRF</PmtMtd>
			<NbOfTxs>1</NbOfTxs>
			<CtrlSum>5555.55</CtrlSum>
			<PmtTpInf>
				<SvcLvl>
					<Cd>SEPA</Cd>
				</SvcLvl>
			</PmtTpInf>
			<ReqdExctnDt>2015-10-15</ReqdExctnDt>
			<Dbtr>
				<Nm>Firma</Nm>
			</Dbtr>
			<DbtrAcct>
				<Id>
					<IBAN>A55555555</IBAN>
				</Id>
			</DbtrAcct>
			<DbtrAgt>
				<FinInstnId>
					<BIC>RREWEF3</BIC>
				</FinInstnId>
			</DbtrAgt>
			<CdtTrfTxInf>
				<PmtId>
					<EndToEndId>1111111</EndToEndId>
				</PmtId>
				<Amt>
					<InstdAmt Ccy="EUR">5555.55</InstdAmt>
				</Amt>
				<CdtrAgt>
					<FinInstnId>
						<BIC>RRR23E</BIC>
					</FinInstnId>
				</CdtrAgt>
				<Cdtr>
					<Nm>HHHH</Nm>
				</Cdtr>
				<CdtrAcct>
					<Id>
						<IBAN>5555555</IBAN>
					</Id>
				</CdtrAcct>
				<Purp>
					<Cd>OTHR</Cd>
				</Purp>
				<RmtInf>
					<Strd>
						<CdtrRefInf>
							<Ref>55555</Ref>
						</CdtrRefInf>
					</Strd>
				</RmtInf>
			</CdtTrfTxInf>
		</PmtInf>
	</CstmrCdtTrfInitn>
</Document>

Benötige das CtrlSum.
Lese xml-Dateien eigentlich immer so aus:


XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Test\test2.xml");
XmlNode node = xmlDoc.SelectSingleNode("/Document/CstmrCdtTrfInitn/GrpHdr/CtrlSum");
string test = node.InnerText;

node ist aber immer NULL - was mache ich hier falsch?

DANKE!

Moderationshinweis von Coffeebean (09.10.2015 - 08:37:06):

Ich hab das XML mal normal formatiert. Wie soll denn einer helfen, wenn das XML absolut unlesbar ist und dazu noch die Darstellung beeinträchtigt? Bitte achte darauf. Mach es uns nicht so schwer dir zu helfen.

private Nachricht | Beiträge des Benutzers
Jamikus
myCSharp.de - Member



Dabei seit:
Beiträge: 251
Herkunft: Oberhausen (NRW)

beantworten | zitieren | melden

Mhh wohl nicht der Erste mit dem Problem: XML Knoten auslesen
private Nachricht | Beiträge des Benutzers
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Der Beitrag wäre genau das Thema. Nur hat er niergendwo seine XML-Datei gepostet oder bin sehe ich jetzt schon den Wald vor lauter Bäumen nicht??
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16148

beantworten | zitieren | melden

Du hast in der XML den Namespace urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 machst diesen aber nirgends bekannt.
Dann findet er halt auch die Nodes nicht ;-)

Ergo: XmlNamespaceManager verwenden.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

DANKE Leute... irgendwie schaffe ich es immer noch nicht:


XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Test\test2.xml");
XmlNamespaceManager nsMan = new XmlNamespaceManager(xmlDoc.NameTable);
nsMan.AddNamespace("", "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03");
XmlNode test = xmlDoc.DocumentElement.SelectSingleNode("/CstmrCdtTrfInitn/GrpHdr/CtrlSum", nsMan);
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16148

beantworten | zitieren | melden

Wie kommst Du auf die Idee, dass die Namespace Bezeichnung "" ist?
Nachgelesen, wie es funktioniert?
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Hi Abt (danke für die Geduld).

Verstehe es leider nicht wirklich.

<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03 pain.001.001.03.xsd">

Was genau ist jetzt der Namespace ( Da 2x xmlns) - das verstehe ich nicht ganz.

Habe es auch schon so probiert:


nsMan.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");


Stand im Moment:


XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Users\Public\Documents\xml\TEST.xml");
XmlNamespaceManager nsMan = new XmlNamespaceManager(xmlDoc.NameTable);
nsMan.AddNamespace("ab", "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03");
XmlNode node3 = xmlDoc.SelectSingleNode("/ab:CstmrCdtTrfInitn/GrpHdr/CtrlSum", nsMan);

Bin ich hier ganz falsch?


Also mit dem Namespace komme ich nicht zurecht... habe jetzt folgendes gefunden:


XmlNode hallo = xmlDoc.GetElementsByTagName("CtrlSum")[0];
String juhu = hallo.InnerText;

Funktionert auch:


XmlNode node3 = xmlDoc.SelectSingleNode("//ab:CtrlSum", nsMan);

Verstehe es Aber nicht - was ist mit den Knoten davor?
Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von matte am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16148

beantworten | zitieren | melden

Bitte les Dich in XPath ein, dann verstehst Du den Unterschied von SelectNode("/.. und SelectNode("//.."
XML gehört zum Grundwissen von .NET, und XPath ist ein absolut erforderlicher Bestandteil davon.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden


var xdoc = XDocument.Load(@"XMLFile1.xml");
var nspace = xdoc.Root.GetDefaultNamespace();
var checksum = Convert.ToDecimal(xdoc.Root.Descendants(nspace + "CtrlSum").First().Value, CultureInfo.InvariantCulture);

Aber mach dir dein Leben ruhig weiter schwer

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)
private Nachricht | Beiträge des Benutzers
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Habe ich hier gemacht:
XPath

Verstehe ich die schreibweise im C# hier nicht ganz dazu:

Laut dieser Erklärung hätte ich das so verstanden:


XmlNode node3 = xmlDoc.SelectSingleNode("//ab:GrpHdr/CtrlSum", nsMan);

oder so:


XmlNode node3 = xmlDoc.SelectSingleNode("/ab:CstmrCdtTrfInitn/GrpHdr/CtrlSum", nsMan);

CtrlSum kommt bei 2x vor deshalb.

Kann mir das jemand anhand eines Beispieles erklären das mehrere Unterknoten hat... weil mit einem funktioniert es..
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von matte am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16148

beantworten | zitieren | melden

Du verwendest SelectSingleNode - das ist Dir bewusst?
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Wenn du unbedingt mit XmlDocument und XPath hantieren willst - kann ich zwar an diesem Beispiel nicht nachvollziehen, aber okay - dann reicht Wikipedia nicht.

XML/XSL/XPath/Einführung

So ziemlich vollständige XPath-Erläuterung. Dazu solltest du dir mal die SelectNode-Methoden anschauen, du hebelst da an der falsch Stelle.

Oder du machst es halt in drei Zeilen inkl. Dokument öffnen mit XDocument.

LaTino

Nachtrag:


var xmldoc = new XmlDocument();
xmldoc.Load(@"XMLFile1.xml");
var nsMan = new XmlNamespaceManager(xmldoc.NameTable);
nsMan.AddNamespace("ns", "urn:iso:std:iso:20022:tech:xsd:pain.001.001.03");
var xmlNode = mldoc.SelectSingleNode("/ns:Document/ns:CstmrCdtTrfInitn/ns:GrpHdr/ns:CtrlSum", nsMan);

Zusatztipp: besorg dir ein ordentliches XML-Tool (wenn ich ISO 20022 lese, gehe ich eigentlich automatisch davon aus, dass Geld für eine LiquidXML-Lizenz vorhanden ist) und lass dir die XPath-Ausdrücke generieren. Bei so einfachen Sachen mag's gehen, aber wenn es etwas komplexer wird, verschwendet man wertvolle Hirnkapazitäten. (daher auch mein wiederholter Tipp mit Linq to xml)
"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)
private Nachricht | Beiträge des Benutzers
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Hi Leute,

sorry ich war mit einer Grippe einige Tage außer Gefecht...

ZUERST mal danke für die Hilfe!!

@Abt... Ja, dachte SingleNode ist hier richtig, da ich ja wirklich nur einen Knoten eine auslesen möchte ...

Habe diese Lösung auf der MSN-Seite gefunden bzw. auch immer wenn ich etwas zu XPath gelesen habe.
Was wäre hier der richtige Weg und warum?


@LTino

var xmlNode = mldoc.SelectSingleNode("/ns:Document/ns:CstmrCdtTrfInitn/ns:GrpHdr/ns:CtrlSum", nsMan); 

Ok ich muss hier überall den NamesSpaceManager angeben....
Zitat
Zusatztipp: besorg dir ein ordentliches XML-Tool (wenn ich ISO 20022 lese, gehe ich eigentlich automatisch davon aus, dass Geld für eine LiquidXML-Lizenz vorhanden ist) und lass dir die XPath-Ausdrücke generieren. Bei so einfachen Sachen mag's gehen, aber wenn es etwas komplexer wird, verschwendet man wertvolle Hirnkapazitäten. (daher auch mein wiederholter Tipp mit Linq to xml)

Das Programm das hier die XML-Dateien erstellt hat mit der IT nicht wirklich etwas zu tun. Dies wird von einer Abteilung im Haus verwendet ( wurde gekauft). Für die IT ist nie Geld übrig

Mit Linq to xml habe ich mich noch nicht beschäftigt.

Dieses Beispiel funktiniert zwar aber ich verstehe es nicht ganz:

var xdoc = XDocument.Load(@"XMLFile1.xml");
 var nspace = xdoc.Root.GetDefaultNamespace();
 var checksum = Convert.ToDecimal(xdoc.Root.Descendants(nspace + "CtrlSum").First().Value, CultureInfo.InvariantCulture); 
Müsste er hier nicht noch mehr finden? "CtrlSum" ist ja öfters vorhanden

Zusatz:
Bin noch nicht sehr lange in der Welt von C# (bin eher in Datenbanken unterwegs) - daher bin ich für eure Geduld sehr dankbar - DANKE.
Mir ist Bewusst das hier ist kein Anfängerforum - jedoch findet man sonst sehr wenige Foren die wirklich helfen bzw. auch Fachkenntnisse haben.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von matte am .
private Nachricht | Beiträge des Benutzers
Taipi88
myCSharp.de - Member

Avatar #avatar-3220.jpg


Dabei seit:
Beiträge: 1044
Herkunft: Mainz

beantworten | zitieren | melden

Hi,

du hast das .First() übersehen. Ja - er findet mehrere - gibt dir allerdings nur den ersten davon als decimal.

LG
private Nachricht | Beiträge des Benutzers
Coffeebean
myCSharp.de - Team

Avatar #avatar-3295.gif


Dabei seit:
Beiträge: 2461
Herkunft: Deutschland/Schweiz

beantworten | zitieren | melden

Bitte beachte: [Hinweis] Wie poste ich richtig? Punkt 1.1. Gerade wenn man noch nicht so lange unterwegs ist.

Enumerable.First-Methode
private Nachricht | Beiträge des Benutzers
LaTino
myCSharp.de - Experte

Avatar #avatar-4122.png


Dabei seit:
Beiträge: 3062
Herkunft: Thüringen

beantworten | zitieren | melden

Zitat von matte
sorry ich war mit einer Grippe einige Tage außer Gefecht...
Erstmal gute Besserung :D
Zitat von matte
@Abt... Ja, dachte SingleNode ist hier richtig, da ich ja wirklich nur einen Knoten eine auslesen möchte :baby:...
Viele Wege führen nach Rom. SelectSingleNode auch, wie du an meinem zweiten Beispiel siehst ;).
Zitat von matte

var xmlNode = mldoc.SelectSingleNode("/ns:Document/ns:CstmrCdtTrfInitn/ns:GrpHdr/ns:CtrlSum", nsMan); 

Ok ich muss hier überall den NamesSpaceManager angeben....
Nein. Der Namespacemanager ist nur ein Verzeichnis von "bekannten" Namespaces, für den Fall, dass ein XML-Dokument verschiedene benutzt. Im XPath musst du für jeden Knoten angeben, in welchem Namespace er definiert ist (das ist auch nötig, weil, wie gesagt jeder Knoten einen anderen ns haben könnte). Der NamespaceManager schaut dann nach, ob dieser ns ihm bekannt ist, und tut, was er tun muss beim Auswerten des XPath.
Zitat von matte
Das Programm das hier die XML-Dateien erstellt hat mit der IT nicht wirklich etwas zu tun. Dies wird von einer Abteilung im Haus verwendet ( wurde gekauft). Für die IT ist nie Geld übrig :D

LiquidXML (zum Beispiel) ist nicht nur zum Erstellen von XML gut. Dokument laden, Rechtsklick auf irgendeinen Knoten -> XPath generieren. So oder ähnlich. Es ist zwar hilfreich, sich damit auszukennen, aber letzten Endes machen einen Tools produktiver.

Zitat von matte
Dieses Beispiel funktiniert zwar aber ich verstehe es nicht ganz:

var xdoc = XDocument.Load(@"XMLFile1.xml");
 var nspace = xdoc.Root.GetDefaultNamespace();
 var checksum = Convert.ToDecimal(xdoc.Root.Descendants(nspace + "CtrlSum").First().Value, CultureInfo.InvariantCulture); 
Müsste er hier nicht noch mehr finden? "CtrlSum" ist ja öfters vorhanden :baby:
Was Taipi88 schrieb. Im übrigen muss man bei solchen Ausdrücken - egal ob Linq2Xml oder XmlDocument - immer relativ genau wissen, was man tut. Da das in diesem speziellen XML verwendete Schema zwingend vorschreibt, dass
a) der CtrlSum-Knoten vorhanden sein MUSS
b) der von dir gewünschte Knoten im ersten Subknoten von Root zu finden sein MUSS

konnte man gefahrlos First() verwenden. In anderen XML-Dokumenten, insbesondere wenn die Reihenfolge oder Existenz nicht vorgeschrieben ist, mag so etwas vor den Baum gehen. Also, Obacht. Macht sich auch gut, Dokumente gegen ihr Schema zu validieren, bevor man sich drauf verlässt.

Edit: uh. https://wiki.xmldation.com/@api/deki/files/443/=ISO20022_Business_Rules_pain.001.001.03.png
Das Schema schreibt die CtrlSum NICHT zwingend vor. Also FirstOrDefault() und auf null prüfen.

LaTino
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von LaTino am .
"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)
private Nachricht | Beiträge des Benutzers
matte
myCSharp.de - Member



Dabei seit:
Beiträge: 70

Themenstarter:

beantworten | zitieren | melden

Das mit dem .First war mir bewusst nur nicht im Zusammenhang mit dem Namespacemanager - habe hier etwas durcheinander gebracht.

ABER VIELEN DANK FÜR die HILFE - glaube es wurde hier alles Beantwortert!
private Nachricht | Beiträge des Benutzers