Parsing XML in C# from stream - c#

I've tried several methods, from Linq to loading the data to an XML document, but i can't seem to be able to return the result that i need.
here's the example XML:
<serv:message xmlns:serv="http://www.webex.com/schemas/2002/06/service" xmlns:com="http://www.webex.com/schemas/2002/06/common" xmlns:event="http://www.webex.com/schemas/2002/06/service/event"><serv:header><serv:response><serv:result>SUCCESS</serv:result><serv:gsbStatus>PRIMARY</serv:gsbStatus></serv:response></serv:header><serv:body><serv:bodyContent xsi:type="event:createEventResponse" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><event:sessionKey>11111111</event:sessionKey><event:guestToken>111111111111111111111</event:guestToken></serv:bodyContent></serv:body></serv:message>
And, here's what i've tried to do:
StreamReader reader = new StreamReader(dataStream);
XmlDocument doc = new XmlDocument();
doc.LoadXml(reader.ReadToEnd());
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
XmlNamespaceManager ns2 = new XmlNamespaceManager(doc.NameTable);
XmlNamespaceManager ns3 = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("serv", "http://www.webex.com/schemas/2002/06/service");
ns2.AddNamespace("com", "http://www.webex.com/schemas/2002/06/common");
ns3.AddNamespace("event", "http://www.webex.com/schemas/2002/06/service/event");
XmlNode node = doc.SelectSingleNode("result",ns);
Yet, for some reason i cannot ever seem to return the actual result, which should be either 'SUCCESS' or 'FAILURE' based on the actual xml above.
How can i do this?

your xpath query is not correct.
try this one :
XmlNode node = doc.SelectSingleNode("//serv:result",ns);
or
XmlNode node = doc.SelectSingleNode("serv:message/serv:header/serv:response/serv:result",ns);

This works:
XDocument doc = XDocument.Load(#"test.xml");
XNamespace serv = "http://www.webex.com/schemas/2002/06/service";
var result = doc.Descendants(serv + "result").First().Value;

Related

Using GetElementsByTagName in C# Windows Form with XML

I'm loading a xml page from a secured website which i want to read with Xml Document.
A part of the xml:
<ActueleVertrekTijden>
<VertrekkendeTrein>
<RitNummer>5070</RitNummer>
<VertrekTijd>2015-03-20T19:42:00+0100</VertrekTijd>
<EindBestemming>Den Haag Centraal</EindBestemming>
<TreinSoort>Sprinter</TreinSoort>
<RouteTekst>Lage Zwaluwe, Dordrecht, Rotterdam C.</RouteTekst>
<Vervoerder>NS</Vervoerder>
<VertrekSpoor wijziging="false">6</VertrekSpoor>
</VertrekkendeTrein>
<VertrekkendeTrein>
<RitNummer>1971</RitNummer>
<VertrekTijd>2015-03-20T19:50:00+0100</VertrekTijd>
<EindBestemming>Venlo</EindBestemming>
<TreinSoort>Intercity</TreinSoort>
<RouteTekst>Tilburg, Eindhoven, Helmond</RouteTekst>
<Vervoerder>NS</Vervoerder>
<VertrekSpoor wijziging="false">4</VertrekSpoor>
<Opmerkingen> // This is not always available, but it is important and specific for a 'VertrekkendeTrein'
<Opmerking>Rijdt vandaag niet</Opmerking>
</Opmerkingen>
</VertrekkendeTrein>
Now i'm using the following code:
string urlo = "the website";
string resultje = HttpGeto(urlo);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(resultje);
XmlNodeList ns = xmlDoc.GetElementsByTagName("VertrekkendeTrein");
//MessageBox.Show(ns[0].InnerXml); //*This part works it shows the xml inside the first "VertrekkendeTrein"*
//*Now I want to read all the items of ns[0] and split it like: GetElementsByTagName("RouteTekst")*
XmlDocument xd1 = new XmlDocument();
xd1.LoadXml(ns[0].InnerXml);
XmlNodeList nsvertrektijdje = xd1.GetElementsByTagName("RouteTekst");
var vty1 = nsvertrektijdje[0].InnerText;
MessageBox.Show(vty1);
The problem which i'm having now is that I can't load ns[0].InnerXml in LoadXml. It gave no result.
Edit:
Now i'm using the following:
string urlo = "website";
string resultje = HttpGeto(urlo);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(resultje);
XmlNodeList ns = xmlDoc.GetElementsByTagName("VertrekkendeTrein");
var element = ns[0] as XmlElement;
XmlNodeList nsvertrektijdje = element.GetElementsByTagName("RouteTekst");
var vty1 = nsvertrektijdje[0].InnerText;
MessageBox.Show(vty1);
But it still doesn't work
The problem is that since the ns[0].InnerXml doesn't have a root node , you are unable to parse the inner xml.
try appending a temp node while you loading xml
xd1.LoadXml("<data>" + ns[0].InnerXml + "</data>");
You can't use InnerXml, as that does not include the VertrekkendeTrein node, so it is not a valid xml document (A document can only have a single root node). You could use OuterXml, but that is wasteful, as you have already parsed the XML.
Your best route here is to cast the XmlNode to an XmlElement and use the GetElementsByTagName method from that.
var element = ns[0] as XmlElement;
XmlNodeList nsvertrektijdje = element.GetElementsByTagName("RouteTekst");
The full code now looks like this:
var xml = #"<ActueleVertrekTijden>
<VertrekkendeTrein>
<RitNummer>5070</RitNummer>
<VertrekTijd>2015-03-20T19:42:00+0100</VertrekTijd>
<EindBestemming>Den Haag Centraal</EindBestemming>
<TreinSoort>Sprinter</TreinSoort>
<RouteTekst>Lage Zwaluwe, Dordrecht, Rotterdam C.</RouteTekst>
<Vervoerder>NS</Vervoerder>
<VertrekSpoor wijziging=""false"">6</VertrekSpoor>
</VertrekkendeTrein>
<VertrekkendeTrein>
<RitNummer> 1971 </RitNummer>
<VertrekTijd> 2015 - 03 - 20T19: 50:00 + 0100 </VertrekTijd >
<EindBestemming> Venlo </EindBestemming>
<TreinSoort> Intercity </TreinSoort>
<RouteTekst> Tilburg, Eindhoven, Helmond </RouteTekst>
<Vervoerder> NS </Vervoerder>
<VertrekSpoor wijziging = ""false""> 4 </VertrekSpoor>
<Opmerkingen> // This is not always available, but it is important and specific for a 'VertrekkendeTrein'
<Opmerking> Rijdt vandaag niet</Opmerking>
</Opmerkingen>
</VertrekkendeTrein></ActueleVertrekTijden>";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
XmlNodeList ns = xmlDoc.GetElementsByTagName("VertrekkendeTrein");
var element = ns[0] as XmlElement;
XmlNodeList nsvertrektijdje = element.GetElementsByTagName("RouteTekst");
var vty1 = nsvertrektijdje[0].InnerText;
MessageBox.Show(vty1);

parse xml that contain colon

I have this XML text:
<test:solution xmlns:test="http://www.test.com/">
<script/>
<test:question>
<test:param name="name1">value 1</test:param>
<test:param name="name2"> value 2</test:param>
</test:question>
</test:solution>
when I run my application that contains those lines:
XmlDocument doc = new XmlDocument();
doc.Load(xmlUrl);
XmlNode testQuestions = doc.SelectSingleNode("/test:solution/test:question");
//XmlNodeList testParamNodeList = testQuestions.SelectNodes("test:param");
It give an error, I know that the error come from the colons, but I don't know how to resolve it.
Thanks for help
try this:
XmlDocument doc = new XmlDocument();
doc.Load(PATH);
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("test", "http://www.test.com/");
XmlNode node = doc.SelectSingleNode("//test:solution//test:question", ns);

Reading attribute of an XML file

I have this XML file, I can read all the the nodes
<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
<CTe xmlns="http://www.portalfiscal.inf.br/cte">
<infCte versao="1.04" ID="CTe3512110414557000014604"></infCte>
</CTe>
</cteProc>
I have tried reading this using C#
string chavecte;
string CaminhoDoArquivo = #"C:\Separados\13512004-procCTe.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(CaminhoDoArquivo); //Carregando o arquivo
chavecte = xmlDoc.SelectSingleNode("infCTe")
.Attributes.GetNamedItem("Id").ToString();
but something is wrong with this code.
If you want to use Linq To Xml
var xDoc = XDocument.Load(CaminhoDoArquivo);
XNamespace ns = "http://www.portalfiscal.inf.br/cte";
var chavecte = xDoc.Descendants(ns+"infCte").First().Attribute("id").Value;
PS: I am assuming your xml's invalid line is as
<infCte versao="1.04" id="CTe3512110414557000014604"></infCte>
replace
chavecte = xmlDoc.SelectSingleNode("infCTe").Attributes.GetNamedItem("Id").Value;
with
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ab", "http://www.portalfiscal.inf.br/cte");
chavecte = xmlDoc.SelectSingleNode("//ab:infCte", nsmgr)
.Attributes.GetNamedItem("Id").Value;
I've also noticed that infCte doesn't have the ID attribute properly defined in your xml
Another possible solution is:
string CaminhoDoArquivo = #"C:\Separados\13512004-procCTe.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(CaminhoDoArquivo); //Carregando o arquivo
// Select the node you're interested in
XmlNode node = xmlDoc.SelectSingleNode("/cteProc/CTe/infCte");
// Read the value of the attribute "ID" of that node
string chavecte = node.Attributes["ID"].Value;

How to Select XML Nodes with XML Namespaces with C#

I have to analyze a XML doc with special namespace using C#, and I get some idea from this post. But my code fail to get the expected XML node, because the XML structure is very special...
There is a namespace in root node in XML
<MDOC xmlns="urn:schemas-microsoft-com/PSS/PSS_Survey01">
Here is my code to get this root node
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("urn", "schemas-microsoft-com/PSS/PSS_Survey01");
XmlNode root = doc.SelectSingleNode("MDOC", nsmgr);
Help me!
I am not sure what is special about your XML structure.
I would write the code little differently
string xmlNamespace = String.Empty;
XmlNamespaceManager nsmgr;
XmlNodeList nodeInfo = FABRequestXML.GetElementsByTagName("RootNodeName");
xmlNamespace = Convert.ToString(nodeInfo[0].Attributes["xmlns"].Value);
nsmgr = new XmlNamespaceManager(MyXml.NameTable);
nsmgr.AddNamespace("AB", xmlNamespace);
XmlNode myNode = MyXml.DocumentElement.SelectSingleNode("AB:NodeName", nsmgr);
Hope that helps

Better way to convert a string to XmlNode in C#

I wanted to convert a string (which obviously is an xml) to an XmlNode in C#.While searching the net I got this code.I would like to know whether this is a good way to convert a string to XmlNode? I have to preform this conversion within a loop, so does it cause any performace issues?
XmlTextReader textReader = new XmlTextReader(new StringReader(xmlContent));
XmlDocument myXmlDocument = new XmlDocument();
XmlNode newNode = myXmlDocument.ReadNode(textReader);
Please reply,
Thanks
Alex
should be straight-forward:
string xmlContent = "<foo></foo>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlContent);
XmlNode newNode = doc.DocumentElement;
or with LINQ if that's an option:
XElement newNode = XDocument.Parse(xmlContent).Root;
The accepted answer works only for single element. XmlNode can have multiple elements like string xmlContent = "<foo></foo><bar></bar>"; (Exception: "There are multiple root elements");
To load multiple elements use this:
string xmlContent = "<foo></foo><bar></bar>";
XmlDocument doc = new XmlDocument();
doc.LoadXml("<singleroot>"+xmlContent+"</singleroot>");
XmlNode newNode = doc.SelectSingleNode("/singleroot");
XmlDocument Doc = new XmlDocument();
Doc.LoadXml(xml);

Categories