I have problem with parse XML, this is my xml:
<Invoice version="6.0.1">
<DocumentType>1</DocumentType>
<ID>FV17116113</ID>
<InvoiceLines>
<InvoiceLine>
<UnitPrice>25</UnitPrice>
</InvoiceLine>
<InvoiceLine>
<UnitPrice>55</UnitPrice>
</InvoiceLine>
</InvoiceLines>
</Invoice>
i try this code:
XmlDocument xml= new XmlDocument();
xml.Load(sourcexml);
foreach (XmlElement row in xml.DocumentElement.SelectNodes("InvoiceLines/InvoiceLine"))
{
}
But i have nothing in element row....
Have you any idea please?
I actually cannot understand your problem?
I guess you should remove xmlns attribute from your Invoice node.
Remove this
xmlns="http://isdoc.cz/namespace/2013"
Then, your code will work
foreach (XmlElement row in xml.DocumentElement.SelectNodes("InvoiceLines/InvoiceLine"))
{
Console.WriteLine(row.InnerText);
}
Related
I have an xml document with setup similiar to this:
<invoice>
<IssueDate>2015-09-07</IssueDate>
<InvoiceType>380<InvoiceType>
<AccountingSupplierParty>
<Party>
<EndpointID></EndpointID>
<PartyName>
<Name>Company test</Name>
</PartyName>
</Party>
</AccountingSupplierParty>
</invoice>
This is just a little piece of the entire xml document, just to show how the file looks.
I would like to check all the elements too see if they have empty values, such as EndpointID in this example (I need to replace empty values with NA).
This is what I have so far:
public static void AddToEmptyElements()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("testXml.xml");
XmlNodeList nodes = xmlDoc.DocumentElement.ChildNodes;
foreach (XmlNode node in nodes)
{
Console.WriteLine(node.Name);
}
}
However, this code will only loop through the childs of the root node and not all the grandchilds (or great grandchilds) such as the <Party> and <EndpointID> elements. How can I include these elements in the loop?
I'm not in an environment to test code right now, but isn't it possible to write a recursive method to loop further down the nodes?
Something like this (untested code):
private static void handleNode(XmlNode node)
{
if(node.HasChildNodes)
{
foreach(XmlNode child in node.ChildNodes)
{
handleNode(child);
}
}
else
Console.WriteLine(node.Name);
}
then call this method in place of your Console.WrintLine()
As Jon Skeet already said, you could do this using LINQ to XML.
XDocument xml = XDocument.Load(path);
var emptyElements = xml.Descendants().Where(xe => String.IsNullOrEmpty(xe.Value));
foreach (var xe in emptyElements)
xe.Value = "NA";
I have xml as follows:
<Reports>
<report>
<name>By Book</name>
<report_type>book</report_type>
<Object>Count Change</Object>
<Slicers detail="detail">
<Namespace>EOD</Namespace>
<BookNode>HighLevel</BookNode>
<DateFrom>T-2</DateFrom>
<DateTo>T-1</DateTo>
<System>NewSystem</System>
</Slicers>
</report>
</Reports>
I simply want to loop through the value of each element of the Xdocument (pref would be any element under Slicers) but to start with just all elements.
When I run the following:
var slicers = from c in config.Elements("Reports")
select c.Value ;
foreach (var xe in slicers)
{
Console.WriteLine(xe);
}
The output is a single line concatenating all the values together.
"By BookbookCount ChangeEODHighLevelT-2T-1NewSystem"
I want to loop through them one at a time, 'By Book' first, run some code then book etc etc.
I am sure this is simple, but cant get round it. I have tried foreach(Xelement in query) but same resulst
i would do it something like this;
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
//load in your xml here
XmlNodeList xnList = doc.SelectNodes("nodeYou'reLookingFor");
//for getting just the splicers you could do "Reports/report/Slicers"
foreach (XmlNode node in xnList)
string namespace = node["Namespace"].InnerText;
//go through all your nodes here
you're creating a xmldoc, loading your xml into it, creating a list which holds each node in the list (at a specified Xpath), and then looping through each. in the loop you can do whatever you want by referencing
node["nodenamehere"].InnerText
I'm trying to traverse an XML document and select certain node attributes. The XML is dynamically generated.
<?xml version="1.0" encoding="ISO-8859-1"?>
<streams>
<stream>
<title>+23 (Panama)</title>
<info resolution="768x420" bitrate="1000kbps"/> ----- Need These
<swfUrl>http://www.freeetv.com/script/mediaplayer/player.swf</swfUrl>
<link>rtmp://200.75.216.156/live/</link>
<pageUrl>http://www.freeetv.com/</pageUrl>
<playpath>livestream</playpath>
<language>Music</language>
<advanced></advanced>
</stream>
</streams>
The code that I'm trying to use with zero luck and Visual Studio saying "No you're wrong. Try 600 more times" is
xDoc.Load("http://127.0.0.1/www/xml.php");
XmlNodeList nodes = xDoc.SelectNodes("/streams/stream");
foreach (XmlNode xn in nodes)
{
ListViewItem lvi = listView1.Items.Add(xn["title"].InnerText);
lvi.SubItems.Add(xn["swfUrl"].InnerText);
lvi.SubItems.Add(xn["link"].InnerText);
lvi.SubItems.Add(xn["pageUrl"].InnerText);
lvi.SubItems.Add(xn["playpath"].InnerText);
lvi.SubItems.Add(xn["language"].InnerText);
lvi.SubItems.Add(xn["advanced"].InnerText);
lvi.SubItems.Add(xn["//info/#resolution"].Value);
}
Please tell me oh wise ones what am I doing wrong?
If you want to select node's attribute using XPath you should use SelectSingleNode method, e.g.:
xn.SelectSingleNode("info/#resolution").Value
To select resolution attribute of your last node you need to use:
xn["info"].Attributes["resolution"].Value
Alternatively, you can try LINQ to XML for the same results (I find its API easier to use):
var doc = XDocument.Parse("http://127.0.0.1/www/xml.php");
foreach (var d in doc.Descendants("stream"))
{
ListViewItem lvi = listView1.Items.Add(d.Element("title").Value);
lvi.SubItems.Add(d.Element("swfUrl").Value);
// ...
vi.SubItems.Add(d.Element("info").Attribute("resolution").Value);
}
Here is an example of LINQ to XML to extract attributes from the entire document of a particular attribute name OR list of attribute names.
var xml = XElement.Parse("http://127.0.0.1/www/xml.php");
// find all attributes of a given name
var attributes = xml
.Descendants()
.Attributes("AttributeName")
// find all attributes of multiple names
var attributes = xml
.Descendants()
.Attributes()
.Where(a => ListOfAttribNames.Contains(a.Name.LocalName))
Replace:
lvi.SubItems.Add(xn["//info/#resolution"].Value);
with:
lvi.SubItems.Add(xn.SelectSingleNode("info/#resolution").Value);
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.
This removes all elements from the document:
XDocument document = XDocument.Load(inputFile);
foreach (XElement element in document.Elements())
{
element.Remove();
}
document.Save(outputFile);
This doesn't have any effect:
XDocument document = XDocument.Load(inputFile);
foreach (XElement element in document.Elements())
{
//element.Remove();
foreach (XElement child in element.Elements())
child.Remove();
}
document.Save(outputFile);
Am I missing something here? Since these are all references to elements within the XDocument, shouldn't the changes take effect? Is there some other way I should be removing nested children from an XDocument?
Thanks!
Apparently when you iterate over element.Elements(), calling a Remove() on one of the children causes the enumerator to yield break. Iterating over element.Elements().ToList() fixed the problem.
Here's an example of another way using System.Xml.XPath (change the xpath query to suit your needs):
const string xml =
#"<xml>
<country>
<states>
<state>arkansas</state>
<state>california</state>
<state>virginia</state>
</states>
</country>
</xml>";
XDocument doc = XDocument.Parse(xml);
doc.XPathSelectElements("//xml/country/states/state[.='arkansas']").ToList()
.ForEach(el => el.Remove());;
Console.WriteLine(doc.ToString());
Console.ReadKey(true);
When using XDocument try this instead:
XDocument document = XDocument.Load(inputFile);
foreach (XElement element in document.Elements())
{
document.Element("Root").SetElementValue(element , null);
}
document.Save(outputFile)
Regards,
Todd