2015-08-05 2 views
2
<bookstore> 
    <book> 
    <bookID>100</bookID> 
    <name> The cat in the hat </name> 
    </book> 
    <book> 
    <bookID>90</bookID> 
    <name> another book </name> 
    </book> 
    <book> 
    <bookID>103</bookID> 
    <name> a new book </name> 
    </book> 
</bookstore> 

Я пытаюсь sellect значение BookID из метода XML document.The я в настоящее время используется в Element(bookID).Value Но иногда BookID приходит как атрибут книги, как это: <book bookID=100> Есть ли способ сделать это в C#, например, как выражение xPath? Большое спасибо!C# выберите атрибут или элемент из XML

+0

Вы должны убедиться, что структура XML фиксируется схемой, прежде чем начать дело с ним. Это избавит вас от многих неприятностей позже. – MarcinJuraszek

+2

В чем проблема с решением, предложенным в [предыдущем вопросе] (http://stackoverflow.com/questions/31778330/c-sharp-sort-by-elements-or-attribute-with-one-method)? – har07

+0

@ har07 Я googling даю ключевое слово и пытаюсь понять это решение. Вот почему я еще не ответил. Я довольно новичок в C#. Извиняюсь .. – user3735871

ответ

2

В XPath вы можете использовать оператор union (|) для объединения запроса, который возвращает другую часть XML. Например:

//book/bookID/text() | //book/@bookID 

выше XPath возвращает текстовое содержимое элемента bookID и bookID атрибута в порядке документа. См. Демонстрацию, которая использует XmlDocument.SelectNodes() для выполнения XPath.

Demo Codes:

var xml = @"<bookstore> 
    <book> 
    <bookID>100</bookID> 
    <name> The cat in the hat </name> 
    </book> 
    <book bookID='90'> 
    <name> a new book </name> 
    </book> 
    <book> 
    <bookID>103</bookID> 
    <name> another book </name> 
    </book> 
</bookstore>"; 
var doc = new XmlDocument(); 
doc.LoadXml(xml); 
var result = doc.SelectNodes("//book/bookID/text() | //book/@bookID"); 
foreach (XmlNode r in result) 
{ 
    Console.WriteLine(r.Value); 
} 

выход:

100 
90 
103 
2

Должно ли это быть выражение XPath или вы можете использовать Linq с системой XDocument.

Например.

var xDocument = XDocument.Parse(@"<bookstore> 
           <book> 
           <bookID>100</bookID> 
           <name> The cat in the hat </name> 
           </book> 
           <book bookID=""90""> 
           <name> another book </name> 
           </book> 
           <book> 
           <bookID>103</bookID> 
           <name> a new book </name> 
           </book> 
           </bookstore>"); 

foreach (var xBook in xDocument.Descendants("book")) 
{ 
    var bookIdNode = xBook.Elements("bookID").FirstOrDefault(); 
    int bookId = 0; 

    ///there is a book id as an element 
    if (bookIdNode != null) 
    { 
     //invalid book id.. should be an int 
     if (!int.TryParse(bookIdNode.Value, out bookId)) 
      continue; 
    } 
    else 
    { 
     var bookIdAttr = xBook.Attributes("bookID").FirstOrDefault(); 
     if (bookIdAttr == null || !int.TryParse(bookIdAttr.Value, out bookId)) 
      continue; 
    } 

    if (bookId == 0) 
     continue; 

    //else we got our book id 

} 

Этот код довольно просто, перебирает над потомками с именем book элемента. Сначала он проверяет, есть ли элемент с именем bookID (с учетом регистра). Если есть попытки проанализировать идентификатор книги как int, используя метод int.TryParse().

Если нет bookID элементов его рядом проверяет, есть ли какие-либо атрибуты с именем bookID и захватывает первый экземпляр (или нуль), используя FirstOrDefault() метод расширения. Если есть экземпляр атрибута bookID, он также пытается проанализировать int, используя метод int.TryParse().

К концу небольшого фрагмента мы проверяем, является ли bookId0, если он равен нулю, мы можем предположить, что что-то пошло не так. Однако это не должно произойти, так как логика должна содержать перечисление и забыть об элементах без элемента bookID или атрибута bookID.

Смежные вопросы