Фильтрация по необязательному элементу (LINQ to XML)
Иногда требуется отфильтровать элемент, даже если он не уверен, что он существует в XML-документе. Поиск можно написать таким образом, чтобы, даже если определенный элемент не имеет дочернего элемента, вы не активируете исключение со ссылкой NULL, отфильтровав его.
Пример. Поиск, который не активирует исключение, если целевой элемент не существует
В следующем примере Child5
элемент не имеет дочернего Type
элемента, но запрос по-прежнему выполняется правильно. В примере используется Elements метод расширения.
XElement root = XElement.Parse(@"<Root>
<Child1>
<Text>Child One Text</Text>
<Type Value=""Yes""/>
</Child1>
<Child2>
<Text>Child Two Text</Text>
<Type Value=""Yes""/>
</Child2>
<Child3>
<Text>Child Three Text</Text>
<Type Value=""No""/>
</Child3>
<Child4>
<Text>Child Four Text</Text>
<Type Value=""Yes""/>
</Child4>
<Child5>
<Text>Child Five Text</Text>
</Child5>
</Root>");
var cList =
from typeElement in root.Elements().Elements("Type")
where (string)typeElement.Attribute("Value") == "Yes"
select (string)typeElement.Parent.Element("Text");
foreach(string str in cList)
Console.WriteLine(str);
Dim root As XElement = _
<Root>
<Child1>
<Text>Child One Text</Text>
<Type Value="Yes"/>
</Child1>
<Child2>
<Text>Child Two Text</Text>
<Type Value="Yes"/>
</Child2>
<Child3>
<Text>Child Three Text</Text>
<Type Value="No"/>
</Child3>
<Child4>
<Text>Child Four Text</Text>
<Type Value="Yes"/>
</Child4>
<Child5>
<Text>Child Five Text</Text>
</Child5>
</Root>
Dim cList As IEnumerable(Of String) = _
From typeElement In root.Elements().<Type> _
Where typeElement.@Value = "Yes" _
Select typeElement.Parent.<Text>.Value
Dim str As String
For Each str In cList
Console.WriteLine(str)
Next
В примере получается следующий вывод.
Child One Text
Child Two Text
Child Four Text
Пример: тот же поиск, но xml в пространстве имен
В следующем примере используется тот же запрос, но для XML, который находится в пространстве имен. Дополнительные сведения см. в обзоре пространств имен.
XElement root = XElement.Parse(@"<Root xmlns='http://www.adatum.com'>
<Child1>
<Text>Child One Text</Text>
<Type Value=""Yes""/>
</Child1>
<Child2>
<Text>Child Two Text</Text>
<Type Value=""Yes""/>
</Child2>
<Child3>
<Text>Child Three Text</Text>
<Type Value=""No""/>
</Child3>
<Child4>
<Text>Child Four Text</Text>
<Type Value=""Yes""/>
</Child4>
<Child5>
<Text>Child Five Text</Text>
</Child5>
</Root>");
XNamespace ad = "http://www.adatum.com";
var cList =
from typeElement in root.Elements().Elements(ad + "Type")
where (string)typeElement.Attribute("Value") == "Yes"
select (string)typeElement.Parent.Element(ad + "Text");
foreach (string str in cList)
Console.WriteLine(str);
Imports <xmlns='http://www.adatum.com'>
Module Module1
Sub Main()
Dim root As XElement = _
<Root>
<Child1>
<Text>Child One Text</Text>
<Type Value="Yes"/>
</Child1>
<Child2>
<Text>Child Two Text</Text>
<Type Value="Yes"/>
</Child2>
<Child3>
<Text>Child Three Text</Text>
<Type Value="No"/>
</Child3>
<Child4>
<Text>Child Four Text</Text>
<Type Value="Yes"/>
</Child4>
<Child5>
<Text>Child Five Text</Text>
</Child5>
</Root>
Dim cList As IEnumerable(Of String) = _
From typeElement In root.Elements().<Type> _
Where typeElement.@Value = "Yes" _
Select typeElement.Parent.<Text>.Value
Dim str As String
For Each str In cList
Console.WriteLine(str)
Next
End Sub
End Module
В примере получается следующий вывод.
Child One Text
Child Two Text
Child Four Text
См. также
- XElement.Attribute
- XContainer.Elements
- Extensions.Elements
- Общие сведения о стандартных операторах запроса (C#)
- Операции проекции (C#)
- Основные запросы (LINQ to XML) (Visual Basic)
- Свойство дочерней оси XML (Visual Basic)
- Свойство оси атрибута XML (Visual Basic)
- Свойство значения XML
- Общие сведения о стандартных операторах запроса (Visual Basic)
- Операции проекции (Visual Basic)