<Employees>
<Employee>
<EmpId>1</EmpId>
<Name>Sam</Name>
<Sex>Male</Sex>
<Phone Type="Home">423-555-0124</Phone>
<Phone Type="Work">424-555-0545</Phone>
</Employee>
</Employees>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
emplyeeDetails = XDocument.Load(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName + "\\LinqToXml\\Xmls\\" + "Employees.xml");
var emplyees = from emp in emplyeeDetails.Descendants("Employee").Take(10)
orderby emp.Element("EmpId").Value ascending
select new
{
Id = emp.Element("EmpId").Value,
Name = emp.Element("Name").Value,
Sex = emp.Element("Sex").Value,
WorkPhone=emp.Element("Phone").Attribute("Type").Value,
HomePhone = emp.Element("Phone").Attribute("Type").Value,
};
DgrdEmployeeDetails.ItemsSource = emplyees.ToList();
}
上記のコードを使用すると、以下の結果を得ることができます。
しかし、WorkPhone
の代わりに列Home
の値424-555-0545
が必要であり、HomePhone
の代わりに列Home
の値423-555-0124
が必要です。
そのために私は何をすべきですか?
Where
メソッドを使用します。
自宅電話番号の場合:
_emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Home").Value
_
仕事電話番号の場合:
_emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value
_
emp.Elements("Phone")
は、emp
のすべての「電話」要素で列挙可能です。Single
は、指定されたプロパティを満たす要素を取得します(プロパティを満たす要素が0個または複数ある場合、エラーが発生します)。phoneElement.Attribute("Type").Value
は、属性「Type」(つまり「Home」または「Work」)の値です。次に、コードは次のようになります。
_var emplyees = from emp in emplyeeDetails.Descendants("Employee").Take(10)
orderby emp.Element("EmpId").Value ascending
select new
{
Id = emp.Element("EmpId").Value,
Name = emp.Element("Name").Value,
Sex = emp.Element("Sex").Value,
WorkPhone = emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Home").Value,
HomePhone = emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value,
};
_
要素emp
にWork phoneまたはHome phone numberがない場合、上記のコードはSingle
で例外を発生させます。このケースに対処するには、コードを次のように変更する必要があります。
_(string)emp.Elements("Phone").SingleOrDefault(phoneElement => phoneElement.Attribute("Type").Value == "Home")
_
SingleOrDefault
は、条件を満たす「Phone」要素がなく、null
にキャストされたstring
が_XElement.Value
_と同等である場合、XElement
と等しくなります。
このコードは、従業員にPhone
要素が存在する場合でも機能します。
var emplyees =
from emp in emplyeeDetails.Descendants("Employee").Take(10)
let phones = emp.Descendants("Phone")
orderby (int)emp.Element("EmpId")
select new
{
Id = (int)emp.Element("EmpId"),
Name = (string)emp.Element("Name"),
Sex = (string)emp.Element("Sex"),
WorkPhone = (string)phones.FirstOrDefault(p => (string)p.Attribute("Type") == "Work"),
HomePhone = (string)phones.FirstOrDefault(p => (string)p.Attribute("Type") == "Home")
};
string
プロパティにアクセスする代わりに、キャスト要素をint
、Value
などに使用します。どうして? xmlに欠落している要素または属性がある場合、NullReferenceException
を取得するためです。ただし、キャストは代わりにデフォルト値を返します。したがって、上記のコードは次のようなxmlでも解析します。
<Employees>
<Employee>
<EmpId>1</EmpId>
<Name>Sam</Name>
<Phone Type="Home">423-555-0124</Phone>
<Phone>524-777-1234</Phone>
</Employee>
</Employees>