c# Parsing XML issue - c#

I am using this code to try and read this XML below, but it is not read anything in the foreach loop and skipping that. Thanks.
C#
XElement _xml;
_xml = XElement.Parse(PostResult);
foreach (XElement value in _xml.Elements("ServiceDelivery")
.Element("StopMonitoringDelivery")
.Elements("MonitoredStopVisit"))
{
StopFeed _item = new StopFeed();
_item.A= value.Element("PublishedLineName").Value;
_item.B = value.Element("DirectionName").Value;
listBox1.Items.Add(_item);
}
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Siri version="1.0" xmlns="http://www.siri.org.uk/">
<ServiceDelivery>
<ResponseTimestamp>2011-10-04T11:45:36.415+01:00</ResponseTimestamp>
<ResponseMessageIdentifier>1d8bc237-2df6-43e6-af56-c750d3089eb6</ResponseMessageIdentifier>
<StopMonitoringDelivery version="1.0">
<ResponseTimestamp>2011-10-04T11:45:36.415+01:00</ResponseTimestamp>
<RequestMessageRef>1</RequestMessageRef>
<MonitoredStopVisit>
<RecordedAtTime>2011-10-04T11:45:36.412+01:00</RecordedAtTime>
<MonitoringRef>020035057</MonitoringRef>
<MonitoredVehicleJourney>
<FramedVehicleJourneyRef>
<DataFrameRef>-</DataFrameRef>
<DatedVehicleJourneyRef>-</DatedVehicleJourneyRef>
</FramedVehicleJourneyRef>
<VehicleMode>bus</VehicleMode>
<PublishedLineName>28</PublishedLineName>
<DirectionName>blahblah</DirectionName>
<OperatorRef>153</OperatorRef>
<MonitoredCall>
<AimedDepartureTime>2011-10- 04T11:48:00.000+01:00</AimedDepartureTime>
</MonitoredCall>
</MonitoredVehicleJourney>
</MonitoredStopVisit>
</StopMonitoringDelivery>
</ServiceDelivery>
</Siri>

I think you forgot the namespace. Have a look at XNamespace
XNamespace xn= "http://www.siri.org.uk/";
foreach (XElement value in _xml.Elements(xn+ "ServiceDelivery")
.Element(xn+ "StopMonitoringDelivery")
.Elements(xn+ "MonitoredStopVisit"))
{
....
}

The root element is Siri.
Either use:
XElement value in _xml.Root.Elements("ServiceDelivery")
.Element("StopMonitoringDelivery")
.Elements("MonitoredStopVisit"))
or
XElement value in _xml.Element("Siri")
.Elements("ServiceDelivery")
.Element("StopMonitoringDelivery")
.Elements("MonitoredStopVisit"))
/B

try _xml.Elements("//ServiceDelivery") or _xml.Elements("Siri/ServiceDelivery"), you forgot that your ServiceDelivery node is child of Siri node.
Or maybe the XML namespace is the problem, check this page and see how XmlNamespaceManager can be used.

Related

Change ALL Tag Name to Lowercase inside XMLDocument

I need to change ALL the Tag name to Lowercase but leave the InnerText or Value as it is. I just found the thread showing how to change the casing for the entire document but NOT just for the Tag names.
Code
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlDoc.OuterXml.ToLower());
Original.xml
<?xml version="1.0" encoding="utf-8" ?>
<ROOT>
<InNeRtAg>SoMe TeXt</InNeRtAg>
<NeStEdElEmEnT>
<InNeRnEsTiNg>SoMe TeXt</InNeRnEsTiNg>
</NeStEdElEmEnT>
</ROOT>
Changing ALL nodes including the root element:
var doc = XDocument.Load("Original.xml");
// also need to change the root element
doc.Root.Name = doc.Root.Name.LocalName.ToLower();
foreach (var element in doc.Descendants().Elements())
{
element.Name = element.Name.LocalName.ToLower();
}
doc.Save("Modified.xml");
Results in Modified.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<innertag>SoMe TeXt</innertag>
<nestedelement>
<innernesting>SoMe TeXt</innernesting>
</nestedelement>
</root>
When using
foreach (var element in doc.Descendants().Elements())
{
element.Name = element.Name.LocalName.ToLower();
}
the root element will not be changed.
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<innertag>SoMe TeXt</innertag>
<nestedelement>
<innernesting>SoMe TeXt</innernesting>
</nestedelement>
</ROOT>
You can try something like this:
var doc = XDocument.Load(filepath);
foreach (var element in doc.Descendants().Elements())
{
element.Name = element.Name.LocalName.ToLower();
}

How can I parse the following xml in c#

I need some help on how to get values of English and studentId from this XML. Maybe it needs some special parsing I can't figure out at the moment.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<processResponse xmlns="http://tempuri.org/">
<processResult>
<xml version="1.0" encoding="UTF-8"?>
<returnedResponse>
<English>94</English>
<Remarks>Excellent</Remarks>
<studentId>tst005</studentId>
<Department>6</Department>
</returnedResponse>
</processResult>
</processResponse>
</soap:Body>
</soap:Envelope>
I have tried the following code:
XmlDocument xdr = new XmlDocument();
xdr.LoadXml(thexml);
XmlNodeList nodelist = xdr.SelectNodes("//processResponse/processResult/returnedResponse");
foreach (XmlNode node in nodelist)
{
string eng = node.SelectSingleNode("English").InnerText;
Response.Write("eng");
}
Do you get an error with invalid XML or does your SelectNodes not find anything?
How about this path
XmlNodeList nodelist = xdr.SelectNodes("/*/*/*/processResponse/processResult/returnedResponse");
You can try with SelectSingleNode, just like this.
var English= xdr.DocumentElement.SelectSingleNode("English").InnerText;
var studentId = xdr.DocumentElement.SelectSingleNode("studentId").InnerText;
1) XML ist invalid at line 6 -> because it does not have a closing tag. If you cannot edit the Service and strip the xml header or encode the resulting xml, you have to strip the line 6 in you consumercode.
2) You have to define the Namespaces!
Btw: I highly recommend using (Linq2XML) XDocument. Your code could look like this:
XDocument xdr = XDocument.Parse(...);
var nodes = xdr.XPathSelectElements("//*[name()='returnedResponse']");
Try this
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);
XmlNodeList nList = doc.GetElementsByTagName("returnedResponse");
foreach (XmlNode node in nList)
{
XElement xelement = XElement.Parse(node.OuterXml);
var Descendents = xelement.Descendants();
foreach (var item in Descendents)
{
//you'll get each of your descendents here
}
}

Very simple XML reading in C#.NET

I want to read the following XML file:
Words.xml:
<?xml version="1.0" encoding="utf-8" ?>
<words>
<word>Bat</word>
<word>Dog</word>
<word>Car</word>
</words>
..using XDocument. I keep getting a "Non white space characters cannot be added to content" error with this code:
XDocument doc = new XDocument("words.xml");
foreach (XElement element in doc.Descendants("word"))
{
Console.WriteLine(element.Value);
}
You need to load the document like this:
XDocument doc = XDocument.Load("words.xml");
The reason your original code fails is you are using XDocument (Object[]) constructor that normally expects list of XElement objects like:
var doc = new XDocument(new XElement("Root"));

How to Remove Root Element in C#/

I'm new to XML & C#.
I want to remove root element without deleting child element.
XML file is strudctured as below.
<?xml version="1.0" encoding="UTF-8"?>
<dataroot generated="2013-07-06T20:26:48" xmlns:od="urn:schemas-microsoft-com:officedata">
<MetaDataSection>
<Name>KR04</Name>
<XMLCreationDate>02.05.2013 9:52:41 </XMLCreationDate>
<Address>AUTOMATIC</Address>
<Age>22</Age>
</MetaDataSection>
</dataroot>
I want to root element "dataroot", so it should look like below.
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataSection>
<Name>KR04</Name>
<XMLCreationDate>02.05.2013 9:52:41 </XMLCreationDate>
<Address>AUTOMATIC</Address>
<Age>22</Age>
</MetaDataSection>
Deleting child elements look like easy, but I don't know how to delete root element only.
Below is the code I've tried so far.
XmlDocument xmlFile = new XmlDocument();
xmlFile.Load("path to xml");
XmlNodeList nodes = xmlFile.SelectNodes("//dataroot");
foreach (XmlElement element in nodes)
{
element.RemoveAll();
}
Is there a way to remove root element only? without deleting child elements?
Thank you in advnace.
Rather than trying to actually remove the root element from an existing object, it looks like the underlying aim is to save (or at least access) the first child element of the root element.
The simplest way to do this is with LINQ to XML - something like this:
XDocument input = XDocument.Load("input.xml");
XElement firstChild = input.Root.Elements().First();
XDocument output = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
firstChild);
output.Save("output.xml");
Or if you don't need the XML declaration:
XDocument input = XDocument.Load("input.xml");
XElement firstChild = input.Root.Elements().First();
firstChild.Save("output.xml");
if you need to do in c# coding means
Solution
foreach (XElement item in Element.Descendants("dataroot").ToList())
{
item.ReplaceWith(item.Nodes());
}

Using XmlTextReader to Loop though XML attributes that have the same name

I am doing some practice code with the XmlTextReader. I have written some very basic XML as shown here:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<task name="mixed_sprite_task_test">
<sprite>
<type>animatedSprite</type>
<id>0</id>
<name>animatedSprite</name>
<fileName>iyezoz</fileName>
<startingPositionX>200</startingPositionX>
<startingPositionY>200</startingPositionY>
<sheetSizeX>12</sheetSizeX>
<sheetSizeY>35</sheetSizeY>
<startingFrameX>0</startingFrameX>
<startingFrameY>0</startingFrameY>
<startingState>standing</startingState>
<movementSpeed>15</movementSpeed>
<frameDelay>0.055</frameDelay>
</sprite>
<sprite>
<type>staticSprite</type>
<id>0</id>
<name>staticSprite</name>
<fileName>Super_Mario_63</fileName>
<startingPositionX>0</startingPositionX>
<startingPositionY>0</startingPositionY>
</sprite>
<sprite>
<type>simpleSprite</type>
<id>0</id>
<name>simpleSprite</name>
<fileName>imgres</fileName>
<startingPositionX>100</startingPositionX>
<startingPositionY>100</startingPositionY>
<movementSpeed>15</movementSpeed>
</sprite>
</task>
This file shows that I have a task. In the task I have 3 sprites.
In my code I want to loop through each sprite and collect the information.
I can get the data from the first sprite with no issue. Is there a certain way to loop through an xml with attributes of the same name?
Thank-you!
I prefer Linq2Xml.
var xDoc = XDocument.Parse(xmlstring); //or XDocument.Load(filename);
var sprites = xDoc.Descendants("sprite")
.Select(s=>s.Elements()
.ToDictionary(e=>e.Name.LocalName,e=>(string)e))
.ToList();
You can use it as
var type = sprites[0]["type"];
or can take a safe action
string delay;
if (sprites[1].TryGetValue("frameDelay", out delay))
{
Console.WriteLine(delay);
}
You can select all the nodes named "sprite"
var myXml = new XmlDocument();
myXml.Load(myDocument);
XmlNode rootElement = myXml.DocumentElement;
foreach (XmlNode item in rootElement.SelectNodes(#"/task/sprite"))
{
// do stuff with node
}

Categories