find an item in xml file - c#

i have a xml file like below
<root>
<Month name="Jan" index="1">
<Day index="2">
<event> sample 1</event>
</Day>
<Day index="3">
<event> sample 2 </event>
</Day>
</Month>
<Month name="Feb" index="2">
<Day index="5">
<event> sample 3 </event>
</Day>
<Day index="2">
<event> sample 4 </event>
</Day>
</Month>
</root>
how can i find special month and day event ?
for example i want getting "sample 2" when month is 1 and day is 2
XmlDocument doc = new XmlDocument();
doc.Load("EventsXML.xml");
XmlNode even= doc.SelectSingleNode("/root/Month[#index='1'] |/root/Month/day[#index='2']");
string str=even.InnerXml.ToString();

You need to modify your xpath to something like this:
XmlNode even= doc.SelectSingleNode("/root/Month[#index='1']/Day[#index='2']/event");
You can also use InnerText rather than InnerXml as you know the content is text, or you can modify the xPath to take this into account:
XmlNode even = doc.SelectSingleNode("/root/Month[#index='1']/Day[#index='2']/event/text()");
string str = even.Value;

An XDocument (Linq-to-XML) answer:
var doc = XDocument.Load(...);
var day = doc.Root
.Descendants("Month")
.Where(e => e.Attributes("index").Value == m)
.Descendants("Day")
.Where(e => e.Attributes("index").Value == d);
('m' and 'd' as string for simplicity)

Related

Grouping particular nodes to their parent nodes inside XML

Below given is my Sample XML:
<Response>
<Transactions>
<Upload>
<DocumentID>1</DocumentID>
<Name>A</Name>
<DocumentID>2</DocumentID>
<Name>B</Name>
</Upload>
<Upload>
<DocumentID>3</DocumentID>
<Name>C</Name>
<DocumentID>4</DocumentID>
<Name>D</Name>
</Upload>
<Upload>
<DocumentID>5</DocumentID>
<Name>E</Name>
<DocumentID>6</DocumentID>
<Name>F</Name>
</Upload>
<Transactions>
</Response>
Below given is my coming output:
<Total>
<DocumentID>1</DocumentId>
<DocumentID>2</DocumentId>
<DocumentID>3</DocumentId>
<DocumentID>4</DocumentId>
<DocumentID>5</DocumentId>
<DocumentID>6</DocumentId>
</Total>
I am using the following given code for getting my output:
var downloadfolder = #"C:\Users\KUMARMOHANTA\Desktop\New folder\test.xml";
var masterfile = new XDocument();
XElement newDocument = new XElement("Total");
masterfile.Add(newDocument);
XDocument xdoc = XDocument.Load(downloadfolder);
masterfile.Root.Add(xdoc.Descendants("DocumentId"));
masterfile.Save(#"C:\Users\KUMARMOHANTA\Desktop\merged_.xml");
But my desired output should be something like this:
<Total>
<Transactions>
<Upload>
<DocumentID>1</DocumentID>
<DocumentID>2</DocumentID>
</Upload>
<Upload>
<DocumentID>3</DocumentID>
<DocumentID>4</DocumentID>
</Upload>
<Upload>
<DocumentID>5</DocumentID>
<DocumentID>6</DocumentID>
</Upload>
<Transactions>
</Total>
Rename the element Transactions to Total. Remove elements with name Name. Then save the file.
Try this:
var downloadfolder = #"C:\Users\KUMARMOHANTA\Desktop\New folder\test.xml";
XDocument xdoc = XDocument.Load(downloadfolder);
xdoc.Root.Name = "Total";
xdoc.Descendants("Upload").Elements("Name").Remove();
xdoc.Save(#"C:\Users\KUMARMOHANTA\Desktop\merged_.xml");
Note that your XML example does not close the Transactions element.

Change XML element value in c#

My C# code:
XDocument doc = XDocument.Load(filename);
IEnumerable<XElement> collection =
doc.Elements("BCIRequest").Elements("Card").Elements("SelectedPIN");
My XML document:
<?xml version="1.0" encoding="utf-8"?>
<BCIRequest Version="2.0"
xmlns="urn:xxxxxx:bci:request">
<Header>
<SenderCode>XX99</SenderCode>
<SenderID>9999</SenderID>
<SequenceNumber>123</SequenceNumber>
<CardGroupCount>2</CardGroupCount>
<CardCount>4</CardCount>
<BlockCount>2</BlockCount>
</Header>
<!--card groups (must precede cards and blocks)-->
<CardGroup RequestID="1">
<CustomerNumber>XX01234567</CustomerNumber>
<CardGroupName Emboss="true">GROUP ONE</CardGroupName>
</CardGroup>
<CardGroup RequestID="2"
RequestRef="87416CB7-DAEF-483A-BD08-1A885531D958">
<CustomerNumber>XX12345678</CustomerNumber>
<CardGroupName Emboss="false">GROUP TWO</CardGroupName>
</CardGroup>
<Card RequestID="3">
<CustomerNumber>XX01234567</CustomerNumber>
<DriverCard>
<Driver Emboss="true">MARGE SIMPSON</Driver>
</DriverCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<GeneratedPIN/>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Card RequestID="4">
<CustomerNumber>XX12345678</CustomerNumber>
<VehicleCard>
<VRN Emboss="true">KYI 830</VRN>
</VehicleCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<SelectedPIN>0123</SelectedPIN>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Card RequestID="5">
<CustomerNumber>XX01234567</CustomerNumber>
<BearerCard>
<Bearer Emboss="true">OPEN XXXXXX</Bearer>
</BearerCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<FleetPIN/>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Block RequestID="6">
<CustomerNumber>XX01234567</CustomerNumber>
<PAN>7002999999999999991</PAN>
</Block>
<Card RequestID="7"
RequestRef="956EA6C5-7D7E-4622-94D0-38CAD9FCC8DF">
<CustomerNumber>XX01234567</CustomerNumber>
<DriverCard>
<Driver Emboss="true">HOMER SIMPSON</Driver>
<VRN Emboss="true">795 DVI</VRN>
</DriverCard>
<EmbossText>SPRINGFIELD POWER</EmbossText>
<CardTypeID>10</CardTypeID>
<TokenTypeID>20</TokenTypeID>
<PurchaseCategoryID>30</PurchaseCategoryID>
<ExpiryDate>2018-12</ExpiryDate>
<Reissue>true</Reissue>
<SelectedPIN>0123</SelectedPIN>
<OdoPrompt>true</OdoPrompt>
<CRNPrompt>true</CRNPrompt>
<!--address with optional fields specified-->
<CardDeliveryAddress OneTimeUse="false">
<ContactName>M xxxx</ContactName>
<ContactTitle>Mr</ContactTitle>
<CompanyName>Sxxxx</CompanyName>
<Line1>Sector 22-F</Line1>
<Line2>Springfield Power Plant</Line2>
<Line3>xxx Road</Line3>
<City>xxxx</City>
<Zipcode>xxxx</Zipcode>
<CountryCode>xxx</CountryCode>
</CardDeliveryAddress>
<!--address with only required fields-->
<PINDeliveryAddress OneTimeUse="true">
<Line1>xxxx</Line1>
<City>xxx</City>
<Zipcode>xxxx</Zipcode>
<CountryCode>xxxx</CountryCode>
</PINDeliveryAddress>
<Limits>
<Value Transaction="unlimited" Daily="200" Weekly="unlimited" Monthly="400"/>
<Volume Transaction="100" Daily="unlimited" Weekly="unlimited" Monthly="unlimited"/>
<Transactions Daily="unlimited" Weekly="unlimited" Monthly="unlimited"/>
<Day Monday="true" Tuesday="true" Wednesday="true" Thursday="true" Friday="true" Saturday="false" Sunday="false"/>
<Time Start="unlimited" End="17:00:00"/>
</Limits>
<Products>
<FuelProductRestrictionID>40</FuelProductRestrictionID>
<NonFuelProductRestrictionID>51</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>52</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>53</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>54</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>55</NonFuelProductRestrictionID>
</Products>
</Card>
<Block RequestID="8"
RequestRef="69A3E44D-DC10-4BEE-9249-1FC3C651BA0E">
<CustomerNumber>xxxxx</CustomerNumber>
<PAN>xxxxxx</PAN>
</Block>
</BCIRequest>
I need to update the element value in the above values. The old value is:
<SelectedPIN>0123</SelectedPIN>
And the new value should be:
<SelectedPIN EncryptedPIN="TKDS" FormNumber="000793906306">****</SelectedPIN>
Can anyone can help me on this?
If I selected the BCIRequest element, it's returning a null value. I've tried many solutions but unable to get one working on this XML file.
There many ways an Xml can be be modified, I prefer XDocument
XDocument doc = XDocument.Parse(input);
foreach (var element in doc.Descendants("SelectedPIN")) // filter if you want single element, in example I modifed for all elements.
{
element.Add(new XAttribute("EncryptedPIN", "TKDS"));
element.Add(new XAttribute("FormNumber", "000793906306"));
element.Value = "xxxxx"; //new value
}
and finally you can save the document using
doc.Save();
Take a look at this Demo
The root node (BCIRequest) contains a namespace so you need to include that into your query. Something like this should work:
XNamespace ns = "urn:xxxxxx:bci:request";
IEnumerable<XElement> collection = doc.Elements(ns + "BCIRequest").Elements(ns + "Card").Elements(ns + "SelectedPIN");

XMl Search and filter in windows phone

<?xml version="1.0" encoding="UTF-8"?>
<root>
<player>
<playerId>1234</playerId>
<playerName>ABCD</playerName>
<line>
<studentId>5612</studentId>
<studentName>WXYZ</studentName>
</line>
</player>
</root>
above shown is my XML,
I have to show "studentName" from XML with filter "playername"
so, how should I do it?
Thanks!
You can use LINQ2XML. Try this:
string xml = #"<?xml version='1.0' encoding='UTF-8'?>
<root>
<player>
<playerId>1234</playerId>
<playerName>ABCD</playerName>
<line>
<studentId>5612</studentId>
<studentName>WXYZ</studentName>
</line>
</player>
</root>";
var doc = XDocument.Parse(xml);
string studentName = (string)doc.Descendants("player")
.Where(p => (string)p.Element("playerName") == "ABCD")
.Descendants("studentName").First();
Looks like a chance for some LINQ to XML
See refs here and here for examples.

Get value from node

I have a question) how can I get value from specific node(info/weather/day/day_part type="День" /tempreture )
<?xml version="1.0" encoding="UTF-8"?>
<info lang="ru" xmlns:x="http://www.yandex.ru/xscript">
+<region id="213" lon="37.617671" lat="55.755768" zoom="10"/>
<traffic lon="37.617671" lat="55.755768" zoom="10" region="213"></traffic>
<weather region="213" climate="1">
<source xmlns:xi="http://www.w3.org/2001/XInclude">mb3d</source>
<day xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Москва</title>
<country>Россия</country>
<time_zone>Europe/Moscow</time_zone>
<summer-time>0</summer-time>
<sun_rise>06:51</sun_rise>
<sunset>20:14</sunset>
<daytime>d</daytime>+<date date="2013-04-05T00:00:00Z"/>
<day_part type="день" typeid="2">
<weather_type>облачно</weather_type>
<weather_code>overcast</weather_code>
<image>http://weather.yandex.ru/i/5.png</image>
<image-v2 size="22x22">http://yandex.st/weather/v-1/i/icons/22x22/ovc_+6.png</image-v2>
<image-v3 size="48x48">http://yandex.st/weather/v-1/i/icons/48x48/ovc.png</image-v3>
<image_number>5</image_number>
<wind_speed>5.0</wind_speed>
<wind_direction id="se">юв</wind_direction>
<dampness>70</dampness>
<pressure>743</pressure>
<temperature color="F2F0E6" class_name="t6">+5</temperature>
<time_zone>Europe/Moscow</time_zone>
<observation_time>17:30</observation_time>
<observation>2013-04-05T17:30:00</observation>
</day_part>
<day_part type="вечер" typeid="3"></day_part>
<day_part type="ночь" typeid="4"></day_part>
<day_part type="утро" typeid="1"></day_part>
<day_part type="день" typeid="2"></day_part>
<night_short></night_short>
<tomorrow></tomorrow>
</day>
<url xmlns:xi="http://www.w3.org/2001/XInclude">http://pogoda.yandex.ru/moscow/</url>
</weather>
</info>
I have code, but how can I specify that I need node with type="День"
XElement elem = xDocument.Element("info");
if (elem != null)
foreach (var el in elem.Elements("weather").Elements("day").Elements("day_part"))
{
var level = el.Element("temperature").Value;
listBox1.Items.Add(level);
};
This block of code returns two values(+5, +6) but I need only one(+5) and throw exception.
First of all - your input XML is not valid and it can't be loaded into XDocument. I fixed it to be:
<?xml version="1.0" encoding="UTF-8"?>
<info lang="ru" xmlns:x="http://www.yandex.ru/xscript">+<region id="213" lon="37.617671" lat="55.755768" zoom="10" />
<traffic lon="37.617671" lat="55.755768" zoom="10" region="213"></traffic>
<weather region="213" climate="1">
<source xmlns:xi="http://www.w3.org/2001/XInclude">mb3d</source>
<day xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Москва</title>
<country>Россия</country>
<time_zone>Europe/Moscow</time_zone>
<summer-time>0</summer-time>
<sun_rise>06:51</sun_rise>
<sunset>20:14</sunset>
<daytime>d</daytime>
<date date="2013-04-05T00:00:00Z"></date>
<day_part type="день" typeid="2">
<weather_type>облачно</weather_type>
<weather_code>overcast</weather_code>
<image>http://weather.yandex.ru/i/5.png</image>
<image-v2 size="22x22">http://yandex.st/weather/v-1/i/icons/22x22/ovc_+6.png</image-v2>
<image-v3 size="48x48">http://yandex.st/weather/v-1/i/icons/48x48/ovc.png</image-v3>
<image_number>5</image_number>
<wind_speed>5.0</wind_speed>
<wind_direction id="se">юв</wind_direction>
<dampness>70</dampness>
<pressure>743</pressure>
<temperature color="F2F0E6" class_name="t6">+5</temperature>
<time_zone>Europe/Moscow</time_zone>
<observation_time>17:30</observation_time>
<observation>2013-04-05T17:30:00</observation>
</day_part>
<day_part type="вечер" typeid="3"></day_part>
<day_part type="ночь" typeid="4"></day_part>
<day_part type="утро" typeid="1"></day_part>
<day_part type="день" typeid="2"></day_part>
<night_short></night_short>
<tomorrow></tomorrow>
</day>
<url xmlns:xi="http://www.w3.org/2001/XInclude">http://pogoda.yandex.ru/moscow/</url>
</weather>
</info>
With that kind of input you can get desired nodes values using XPathSelectElements extension method:
var results = xDocument.XPathSelectElements("info/weather/day/day_part[#type='день']/temperature")
.Select(e => (string)e)
.ToList();
For XML document shown above results contains one string value: +5.
However, I would suggest searching day_part element using typeid attribute value instead of type:
var results = xDocument.XPathSelectElements("info/weather/day/day_part[#typeid=2]/temperature")
.Select(e => (string)e)
.ToList();
The same results, but less chance to fail because of encoding.
You can then fill your ListBox:
foreach (var value in results))
{
listBox1.Items.Add(value);
};
Try something like this
if (elem != null)
elem.Descendants("day_part").Where(el => el.Attribute("type").Value == "день")
.ToList().ForEach(el => listBox1.Items.Add(el.Element("temperature").Value));
You can use XPath extension for XLinq:
using System.Xml.Linq;
using System.Xml.XPath;
...
var doc = XDocument.Load("test.xml");
IEnumerable<XElement> dayElements = doc.XPathSelectElements("/info/weather/day/day_part[#type=\"день\"]");

XML string to XML document

I have a whole XML document in a String which i need to convert to a XML document and parse tags in the document
This code sample is taken from csharp-examples.net, written by Jan Slama:
To find nodes in an XML file you can use XPath expressions. Method XmlNode.Selec­tNodes returns a list of nodes selected by the XPath string. Method XmlNode.Selec­tSingleNode finds the first node that matches the XPath string.
XML:
<Names>
<Name>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</Name>
<Name>
<FirstName>James</FirstName>
<LastName>White</LastName>
</Name>
</Names>
CODE:
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/Names/Name");
foreach (XmlNode xn in xnList)
{
string firstName = xn["FirstName"].InnerText;
string lastName = xn["LastName"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
}
Using Linq to xml
Add a reference to System.Xml.Linq
and use
XDocument.Parse(string xmlString)
Edit: Sample follows, xml data (TestConfig.xml)..
<?xml version="1.0"?>
<Tests>
<Test TestId="0001" TestType="CMD">
<Name>Convert number to string</Name>
<CommandLine>Examp1.EXE</CommandLine>
<Input>1</Input>
<Output>One</Output>
</Test>
<Test TestId="0002" TestType="CMD">
<Name>Find succeeding characters</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>abc</Input>
<Output>def</Output>
</Test>
<Test TestId="0003" TestType="GUI">
<Name>Convert multiple numbers to strings</Name>
<CommandLine>Examp2.EXE /Verbose</CommandLine>
<Input>123</Input>
<Output>One Two Three</Output>
</Test>
<Test TestId="0004" TestType="GUI">
<Name>Find correlated key</Name>
<CommandLine>Examp3.EXE</CommandLine>
<Input>a1</Input>
<Output>b1</Output>
</Test>
<Test TestId="0005" TestType="GUI">
<Name>Count characters</Name>
<CommandLine>FinalExamp.EXE</CommandLine>
<Input>This is a test</Input>
<Output>14</Output>
</Test>
<Test TestId="0006" TestType="GUI">
<Name>Another Test</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>Test Input</Input>
<Output>10</Output>
</Test>
</Tests>
C# usage...
XElement root = XElement.Load("TestConfig.xml");
IEnumerable<XElement> tests =
from el in root.Elements("Test")
where (string)el.Element("CommandLine") == "Examp2.EXE"
select el;
foreach (XElement el in tests)
Console.WriteLine((string)el.Attribute("TestId"));
This code produces the following output:
0002
0006
Depending on what document type you want you can use XmlDocument.LoadXml or XDocument.Load.
Try this code:
var myXmlDocument = new XmlDocument();
myXmlDocument.LoadXml(theString);

Categories