Reputation: 53
Here is my XML sample. I want to select SystemSetting's value if ID = 123
. But I can't figure out how. How can I select SystemSetting
value if id's value equal to 123 ?
<?xml version="1.0" encoding="utf-8" ?>
<Private>
<System>
<ID>123</ID>
<NAME>Test</NAME>
<SystemSetting>128</SystemSetting>
<SystemSettingCS>127</SystemSettingCS>
</System>
<System>
<ID>124</ID>
<NAME>Test2</NAME>
<SystemSetting>128</SystemSetting>
<SystemSettingCS>127</SystemSettingCS>
</System>
<System>
<ID>0</ID>
<NAME>Test</NAME>
<SystemSetting>5</SystemSetting>
<SystemSettingCS>250</SystemSettingCS>
</System>
</Private>
Here's what I tried:
var doc = XDocument.Load(Application.StartupPath+ @"\Settings.xml");
var q = from Ana in doc.Descendants("Private")
from sistem in Ana.Elements("System")
where (int)sistem.Element("ID") == 123
from assetText in Sistem.Elements("System")
select assetText.Element("SystemSetting");
MessageBox.Show(q.ToString());
thnx for help.
Upvotes: 4
Views: 108
Reputation: 11955
Was a Linq question, but there is an alternate XPath approach, but the class defined below could work in either scenario.
Define a class to read from the parent System element:
public class XSystem
{
public XSystem(XElement xSystem) { self = xSystem; }
XElement self;
public int Id { get { return (int)self.Element("ID"); } }
public string Name { get { return self.Element("NAME").Value; } }
public int SystemSetting { get { return (int)self.Element("SystemSetting"); } }
public int SystemSettingCS { get { return (int)self.Element("SystemSettingCS"); } }
}
Then find your System element that has a child ID element of 123.
int id = 123;
string xpath = string.Format("//System[ID={0}", id);
XElement x = doc.XPathSelectElement(xpath);
Then plug it into the class:
XSystem system = new XSystem(x);
Then read the value you want:
int systemSetting = system.SystemSetting;
XPath is defined with using System.Xml.XPath;
Upvotes: 0
Reputation: 116108
Xpath (System.Xml.XPath) can really help here
var system = doc.XPathSelectElement("//System[ID[text()='123']]");
var val = system.Element("SystemSetting").Value;
or with a single line
var s = (string)doc.XPathSelectElement("//System[ID[text()='123']]/SystemSetting");
Upvotes: 1
Reputation: 1500405
I think you're making this more complicated than you need to. I think you just need:
var query = doc.Descendants("Private") // Or just doc.Root
.Elements("System")
.Where(x => (int) x.Element("ID") == 123)
.Select(x => x.Element("SystemSetting"))
.FirstOrDefault();
That will select the first matching element, admittedly. The type of query
is then XElement
; if you take off the FirstOrDefault()
part, it will return an IEnumerable<XElement>
, for all matching elements.
If you want just the value instead of the element, you can change the Select
to:
.Select(x => (string) x.Element("SystemSetting"))
or
.Select(x => x.Element("SystemSetting").Value)
(The first will return null
if there's no SystemSetting
element; the second will throw an exception.)
Upvotes: 2
Reputation: 236208
var q = from s in doc.Descendants("System")
where (int)s.Element("ID") == 123
select (int)s.Element("SystemSetting");
And show result (q
will have IEnumerable<int>
type):
if (q.Any())
MessageBox.Show("SystemSettings = " + q.First());
else
MessageBox.Show("System not found");
Upvotes: 0
Reputation: 3788
Your almost there
var xmlFile = XElement.Load(@"c:\\test.xml");
var query =
from e in xmlFile.Elements()
where e.Element("ID").Value == "123"
select e.Element("SystemSetting").Value;
Upvotes: 0