Как извлечь значения элемента (LINQ to XML)
Обновлен: November 2007
В этом разделе показано получение значений элементов. Это можно сделать двумя основными способами. Первый способ состоит в приведении XElement или XAttribute к желаемому типу. Оператор явного преобразования, который преобразует содержимое элемента или атрибута в указанный тип и присваивает полученное значение указанной переменной. Иначе можно использовать свойство XElement.Value или XAttribute.Value.
Однако при использовании C# приведение, как правило, является лучшим подходом. В частности, становится проще написание кода, обеспечивающего получение значения элемента или атрибута, который может существовать или не существовать, после приведения элемента (или атрибута) к типу, допускающему значение NULL. Это демонстрирует последний пример из данного раздела. Однако нельзя так задать содержимое элемента через приведение, как через свойство XElement.Value.
При использовании Visual Basic лучшим подходом является использование свойства XElement.Value.
Пример
Для получения значения элемента нужно просто привести объект XElement к желаемому типу. Всегда можно привести элемент к строке следующим образом:
XElement e = new XElement("StringElement", "abcde");
Console.WriteLine(e);
Console.WriteLine("Value of e:" + (string)e);
Dim e As XElement = <StringElement>abcde</StringElement>
Console.WriteLine(e)
Console.WriteLine("Value of e:" & e.Value)
В этом примере происходит вывод следующих данных:
<StringElement>abcde</StringElement>
Value of e:abcde
Также можно приводить элементы к типам, отличным от строковых. Например, если имеется элемент, содержащий целое число, его можно привести к типу int, как показано в следующем коде:
XElement e = new XElement("Age", "44");
Console.WriteLine(e);
Console.WriteLine("Value of e:" + (int)e);
Dim e As XElement = <Age>44</Age>
Console.WriteLine(e)
Console.WriteLine("Value of e:" & CInt(e))
В этом примере происходит вывод следующих данных:
<Age>44</Age>
Value of e:44
LINQ to XML предоставляет операторы явного приведения для следующих типов данных: string, bool, bool?, int, int?, uint, uint?, long, long?, ulong, ulong?, float, float?, double, double?, decimal, decimal?, DateTime, DateTime?, TimeSpan, TimeSpan?, GUID и GUID?.
LINQ to XMLпредоставляет аналогичные операторы приведения для объектов XAttribute.
Свойство Value может использоваться для получения содержимого элемента:
XElement e = new XElement("StringElement", "abcde");
Console.WriteLine(e);
Console.WriteLine("Value of e:" + e.Value);
Dim e As XElement = <StringElement>abcde</StringElement>
Console.WriteLine(e)
Console.WriteLine("Value of e:" & e.Value)
В этом примере происходит вывод следующих данных:
<StringElement>abcde</StringElement>
Value of e:abcde
Иногда осуществляются попытки получить значение элемента, в отношении которого неизвестно, существует ли он. В этом случае назначение приведенному элементу типа, допускающего значение NULL (либо типа string, либо одного из типов в .NET Framework, допускающих значение NULL), приводит к тому, что если элемент не существует, то переменной просто присваивается значение null (Nothing в Visual Basic). В следующем коде показано, что при отсутствии сведений о том, существует ли элемент, проще использовать приведение типа, чем свойство Value.
XElement root = new XElement("Root",
new XElement("Child1", "child 1 content"),
new XElement("Child2", "2")
);
// The following assignments show why it is easier to use
// casting when the element might or might not exist.
string c1 = (string)root.Element("Child1");
Console.WriteLine("c1:{0}", c1 == null ? "element does not exist" : c1);
int? c2 = (int?)root.Element("Child2");
Console.WriteLine("c2:{0}", c2 == null ? "element does not exist" : c2.ToString());
string c3 = (string)root.Element("Child3");
Console.WriteLine("c3:{0}", c3 == null ? "element does not exist" : c3);
int? c4 = (int?)root.Element("Child4");
Console.WriteLine("c4:{0}", c4 == null ? "element does not exist" : c4.ToString());
Console.WriteLine();
// The following assignments show the required code when using
// the Value property when the element might or might not exist.
// Notice that this is more difficult than the casting approach.
XElement e1 = root.Element("Child1");
string v1;
if (e1 == null)
v1 = null;
else
v1 = e1.Value;
Console.WriteLine("v1:{0}", v1 == null ? "element does not exist" : v1);
XElement e2 = root.Element("Child2");
int? v2;
if (e2 == null)
v2 = null;
else
v2 = Int32.Parse(e2.Value);
Console.WriteLine("v2:{0}", v2 == null ? "element does not exist" : v2.ToString());
XElement e3 = root.Element("Child3");
string v3;
if (e3 == null)
v3 = null;
else
v3 = e3.Value;
Console.WriteLine("v3:{0}", v3 == null ? "element does not exist" : v3);
XElement e4 = root.Element("Child4");
int? v4;
if (e4 == null)
v4 = null;
else
v4 = Int32.Parse(e4.Value);
Console.WriteLine("v4:{0}", v4 == null ? "element does not exist" : v4.ToString());
Dim root As XElement = <Root>
<Child1>child 1 content</Child1>
<Child2>2</Child2>
</Root>
' The following assignments show why it is easier to use
' casting when the element might or might not exist.
Dim c1 As String = CStr(root.Element("Child1"))
Console.WriteLine("c1:{0}", IIf(c1 Is Nothing, "element does not exist", c1))
Dim c2 As Nullable(Of Integer) = CType(root.Element("Child2"), Nullable(Of Integer))
Console.WriteLine("c2:{0}", IIf(Not (c2.HasValue), "element does not exist", c2.ToString()))
Dim c3 As String = CStr(root.Element("Child3"))
Console.WriteLine("c3:{0}", IIf(c3 Is Nothing, "element does not exist", c3))
Dim c4 As Nullable(Of Integer) = CType(root.Element("Child4"), Nullable(Of Integer))
Console.WriteLine("c4:{0}", IIf(Not (c4.HasValue), "element does not exist", c4.ToString()))
Console.WriteLine()
' The following assignments show the required code when using
' the Value property when the attribute might or might not exist.
' Notice that this is more difficult than the casting approach.
Dim e1 As XElement = root.Element("Child1")
Dim v1 As String
If (e1 Is Nothing) Then
v1 = Nothing
Else
v1 = e1.Value
End If
Console.WriteLine("v1:{0}", IIf(v1 Is Nothing, "element does not exist", v1))
Dim e2 As XElement = root.Element("Child2")
Dim v2 As Nullable(Of Integer)
If (e2 Is Nothing) Then
v2 = Nothing
Else
v2 = e2.Value
End If
Console.WriteLine("v2:{0}", IIf(Not (v2.HasValue), "element does not exist", v2))
Dim e3 As XElement = root.Element("Child3")
Dim v3 As String
If (e3 Is Nothing) Then
v3 = Nothing
Else
v3 = e3.Value
End If
Console.WriteLine("v3:{0}", IIf(v3 Is Nothing, "element does not exist", v3))
Dim e4 As XElement = root.Element("Child4")
Dim v4 As Nullable(Of Integer)
If (e4 Is Nothing) Then
v4 = Nothing
Else
v4 = e4.Value
End If
Console.WriteLine("v4:{0}", IIf(Not (v4.HasValue), "element does not exist", v4))
Этот код выводит следующие результаты:
c1:child 1 content
c2:2
c3:element does not exist
c4:element does not exist
v1:child 1 content
v2:2
v3:element does not exist
v4:element does not exist
Как правило, использование приведения для получения содержимого элементов и атрибутов позволяет создавать более простой код.