I have a xml file like this:
<Contacts>
<CommandID>
ShowInstalledProducts
</CommandID>
</Contacts>
I need to iterate through a list of xml files and retrieve the value of CommandId ( in this case ShowInstalledProducts), for each ...
I am very new to xml. can someone please help me with the same. I am trying to achieve this using Linq. (other solutions are also welcome though)
DirectoryInfo directoryInfo = new DirectoryInfo(#"T:\Commands");
FileInfo[] fileInfo = directoryInfo.GetFiles();
foreach (FileInfo loop in fileInfo)
{
string doc = File.ReadAllText(loop.FullName);
XmlDocument XMLDoc = new XmlDocument();
XMLDoc.Load(doc);
XMLDoc= stripDocumentNamespace(XMLDoc);
//id = XMLDoc.Descendants("CommandID").First().Value;
}
This is what i have done till now , im reading the files , and trying to ger the descendants. however there are multiple in each xml file , and i need to retrieve the value of each . stuck here :(
Step 1: Go to linqpad.net and download the Linqpad application. It is a simple editor allowing you to write, run, and play around with Linq expression. Also, it has a lot of built in examples to learn from. (You might have to select Help --> Veiw samples to open this):
Step 2: Paste the following code into the editor, and press F5 to run it (make sure C# Statement(s) is selected for "Language" above it though!). Play around and tweak it as you like / need.
var bench = XElement.Parse(#"<Contacts>
<Node>
Something
</Node>
<Node>
Something else
</Node>
</Contacts>");
var listOfNodes = bench.Elements();
listOfNodes.Dump();
var content = listOfNodes.Select(x => x.Value);
content.Dump();
This should be enough to get you started. Enjoy! :)
fileInfo.SelectMany(fi => XDocument
.Load(fi.FullName)
.Descendants("CommandID")
.Select(e=>e.Value))
This LINQ code should return the list of all CommandId values of all files.
Related
I am trying to fix a piece of code that is not doing what I want it to do. The code was left by an engineer who claimed it was working perfectly. He has been using XPATH instead of Linq, so for the short term I'm looking for a solution based on XPATH.
I've searched the web, but am unable to convert what I've found into a working solution.
The XML looks like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Orders>
<Order>
<OrderId>6175</OrderId>
<OrderNumber>6175</OrderNumber>
<OrderDate>2016-08-19 13:17:41</OrderDate>
<OrderLineItems>
<ItemName>Name of Item</ItemName>
<Quantity>1</Quantity>
<Meta/>
</OrderLineItems>
</Order>
</Orders>
The script he created with Visual Studio 2008 that concerns reading the XML looks like:
public override void CreateNewOutputRows()
{
string filename = Variables.strFileInLoop;
XmlDocument doc = new XmlDocument();
doc.Load(filename);
// loop orders
foreach (XmlNode shipmentNode in doc.DocumentElement.SelectNodes("/Orders/Order"))
{
OutputOrdersBuffer.AddRow();
String OrderId = GetNodeText("OrderId", shipmentNode).Trim();
OutputOrdersBuffer.OrderId = OrderId;
OutputOrdersBuffer.OrderNumber = GetNodeText("OrderNumber", shipmentNode).Trim();
OutputOrdersBuffer.OrderDate = GetNodeText("OrderDate", shipmentNode).Trim();
String replace = #"C:\Projects\Customername\IN\";
OutputOrdersBuffer.FileName = filename.Replace(replace, "");
foreach (XmlNode OrderLineItemNode in shipmentNode.SelectNodes("/Orders/Order/OrderLineItems"))
{
OutputOrderLinesBuffer.AddRow();
OutputOrderLinesBuffer.OrderId = OrderId;
OutputOrderLinesBuffer.ItemName = GetNodeText("ItemName", OrderLineItemNode).Trim();
OutputOrderLinesBuffer.Quantity = GetNodeText("Quantity", OrderLineItemNode).Trim();
OutputOrderLinesBuffer.Meta = GetNodeText("Meta", OrderLineItemNode).Trim();
}
}
}
What happens when we try to import an XML with multiple orders is that the code attaches all OrderLineItems to all Orders.
So if there are 10 unique orders in the file with 2 OrderLineItems it put out 10 Orders with 20 OrderLineItems each.
As I said, I've looked everywhere (I think) but am unable to convert what I've found to a solution where the OrderLineItems are only linked to the order they belong to.
The iteration within an order uses an XPath expression
/Orders/Order/OrderLineItems
that goes through the entire document every time, as the starting / in indicates. This is why all order line items are included in all orders.
Changing the XPath expression to take shipmentNode as the context item, which happens implicitly if the XPath expression does not begin with a /, and navigating from there to its OrderLineItems children should help:
foreach (XmlNode OrderLineItemNode in shipmentNode.SelectNodes("OrderLineItems"))
An analogy with a file system on the command line usually helps when starting with XPath: the context item behaves like a working directory, and one can either change the directory with an absolute path (starting with /), or with a relative path to the current directory (starting with ./, which also works in XPath). Of course XPath is different as it is set-oriented, but this analogy helps getting into the right mindset for navigation.
I am starting to work with xml and I am trying to know if there is a way to search a code in this.
Here you are my xml
<?xml version="1.0" encoding="UTF-8"?>
<doctors_hospital>
<doctor>
<code>1757D</code>
<name>one</name>
</doctor>
<doctor>
<code>1169L</code>
<name>two</name>
</doctor>
... continues xml
</doctors_hospital>
I want to look for the code "aab" using c#, and this is my code..
var document =new XmlDocument();
document.Load("O:\\test\\doctor.xml");
XmlNode doctor;
XmlNode root = document.DocumentElement;
doctor = root.SelectSingleNode("/doctors_hospital/doctor/code='aab'");
I can not do this. any suggestion? thanks
Assuming SelectingSingleNode takes a standard XPath expression, what you want to use is
/doctors_hospital/doctor[code='aab']
This will select the entire doctor node with the matching code value.
I agree with Jim, alternatively you could also use Linq to Xml and do this.
XDocument doc = XDocument.Load(filepath);
var codeExist = doc.Descendants("code").Any(x=>(string)x.Value == "1169L");
Check this Demo
I want to get the data from XML File using C# and i need to assign this data to a dto. Here i need to consider performance also when getting the data from xml file. I already used xml deserialization to get the data from xml file but it is taking lot of time to get the data from large xml files. Please suggest me a solution considering performance using C#.
If your XML file is too huge then you can use the XMLReader. Also you can look into the LINQ to XML option.
Example:
<Branch>
<Node>
<MyNode>
<SubNode code=\"0\">
My message
</SubNode>
</MyNode>
</Node>
</Branch>
Using LINQ to XML
var doc = XDocument.Parse(xml);
var subnode = from x in doc.Descendants("SubNode")
select new
{
code = x.Attribute("code").Value,
msg = x.Value.Trim()
};
foreach (var e in subnode)
{
}
<SMSWall run="yes" nonstop="False">
<starttime>10:15:25 PM</starttime>
<endtime>10:15:25 PM</endtime>
</SMSWall>
<MediaPlayer run="yes" nonstop="False">
<starttime>10:15:25 PM</starttime>
<endtime>10:15:25 PM</endtime>
</MediaPlayer>
<Bidding run="yes" nonstop="False">
<starttime>10:15:25 PM</starttime>
<endtime>10:15:25 PM</endtime>
</Bidding>
This is my xml file. Now I want to read the xml, store the value in a variable (and also want the data to read from the string), and leave the .xml file so that it can be deleted.I also want to read the value node wise like:
XmlDocument document = new XmlDocument();
document.Load("Schedule.xml");
XmlNode ht=document.SelectSingleNode("SMSWall/#run");
Your current XML file is not in correct format (i.e save it as .xml and open it with IE, you will give an error). So you should add <root> ... </root> (or other name).
In all I think best way to treat with XML is using System.Xml.Linq library, like XDocument and XElement :
Loading data: XDocument.Load(filename);
Creating item: XElement root = new XElement("Root");
Searching: document.Descendants("Root"), ...
See MSDN for other samples.
I prefer to create a DataSet and then use it like this:
DataSet1 ds = new DataSet1();
ds.ReadXml("test.xml", XmlReadMode.ReadSchema);
//do something
ds.WriteXml("test.xml", XmlReadMode.ReadSchema);
A typed DataSet will provide you typed tables and rows. You can get rows by index or query. You can find more about the here.
I have looked and can't find the answer, I'm sure I'm just not looking for the right keywords, lol.
I have an XML file that I display in a datagridview, this all works fine. I'm trying to implant where I can click a button and 'reload' the datagridview with only certain parts of the xml file.
I will describe better. Just bear with me, I'm not the best at explaining.
This is the layout of my xml file.
<?xml version="1.0"?>
<Movies>
<Name Name="Saw" Type="Horror" Year="2004-10-29" Overview="Overview">Saw</Name>
<Name Name="Saw II" Type="Horror" Year="2005-10-28" Overview="Overview">Saw II</Name>
<Name Name="Speed" Type="Action" Year="1994-06-10" Overview="Overview">Speed</Name>
<Name Name="Batman Begins" Type="Action" Year="2005-06-17" Overview="Overview">Batman Begins</Name>
</Movies>
When I display normally I have it in a grid view like so.
I had to upload image elsewhere the site wouldn't let me put it here.
enter link description here
Now what I'm trying to do is make is where when I click a button I can display only certain Movie Types. Say for example, click a button and only display movies that are "Action".
I have found information on this and got where I can select only the actions. I got them to pop up in messageboxs'
XmlDocument xml = new XmlDocument();
xml.Load("movie.xml");
XmlNodeList xnList = xml.SelectNodes("/Movies/Name[#Type='Action']");
foreach (XmlNode xn in xnList)
{
MessageBox.Show(xn.InnerText);
}
This actually shows say from the image the 2 movies that are action. But I can't figure out how to reload the datagridview with only these entries, and prefer with all information as before.
If I didn't explain clearly please say so, as I said before I know I"m not the best at explaining things.
One way is to load the xml into a DataTable. Then you can use its in-memory filtering capability to filter the grid.
DataSet ds = new DataSet();
ds.ReadXml("Movies.xml");
this.dataGridView.DataSource = ds.Tables[0];
Then you can filter it like this
private void FilterByType(string type)
{
var dataView = ((DataTable) this.dataGridView.DataSource).DefaultView;
dataView.RowFilter = "(Type = '" + type + "')";
}
To filter by substring use this syntax
dataView.RowFilter = "(Type LIKE *'" + substring + "*')";