如何使用C#xmlreader获取XML中特定元素的值类

问题描述:

我有这个XML文件,我想使用C#xmlreader类读取作者和书名ID“bk101”的标题值。我无法获得该特定ID的作者和标题的价值。如何使用C#xmlreader获取XML中特定元素的值类

<?xml version="1.0"?> 
<catalog> 
    <book id="bk101"> 
     <author>Gambardella, Matthew</author> 
     <title>XML Developer's Guide</title> 
     <genre>Computer</genre> 
     <price>44.95</price> 
     <publish_date>2000-10-01</publish_date> 
     <description>An in-depth look at creating applications 
     with XML.</description> 
    </book> 
    <book id="bk102"> 
     <author>Ralls, Kim</author> 
     <title>Midnight Rain</title> 
     <genre>Fantasy</genre> 
     <price>5.95</price> 
     <publish_date>2000-12-16</publish_date> 
     <description>A former architect battles corporate zombies, 
     an evil sorceress, and her own childhood to become queen 
     of the world.</description> 
    </book> 
    <book id="bk103"> 
     <author>Corets, Eva</author> 
     <title>Maeve Ascendant</title> 
     <genre>Fantasy</genre> 
     <price>5.95</price> 
     <publish_date>2000-11-17</publish_date> 
     <description>After the collapse of a nanotechnology 
     society in England, the young survivors lay the 
     foundation for a new society.</description> 
    </book> 
    <book id="bk104"> 
     <author>Corets, Eva</author> 
     <title>Oberon's Legacy</title> 
     <genre>Fantasy</genre> 
     <price>5.95</price> 
     <publish_date>2001-03-10</publish_date> 
     <description>In post-apocalypse England, the mysterious 
     agent known only as Oberon helps to create a new life 
     for the inhabitants of London. Sequel to Maeve 
     Ascendant.</description> 
    </book> 
    <book id="bk105"> 
     <author>Corets, Eva</author> 
     <title>The Sundered Grail</title> 
     <genre>Fantasy</genre> 
     <price>5.95</price> 
     <publish_date>2001-09-10</publish_date> 
     <description>The two daughters of Maeve, half-sisters, 
     battle one another for control of England. Sequel to 
     Oberon's Legacy.</description> 
    </book> 
    <book id="bk106"> 
     <author>Randall, Cynthia</author> 
     <title>Lover Birds</title> 
     <genre>Romance</genre> 
     <price>4.95</price> 
     <publish_date>2000-09-02</publish_date> 
     <description>When Carla meets Paul at an ornithology 
     conference, tempers fly as feathers get ruffled.</description> 
    </book> 
    <book id="bk107"> 
     <author>Thurman, Paula</author> 
     <title>Splish Splash</title> 
     <genre>Romance</genre> 
     <price>4.95</price> 
     <publish_date>2000-11-02</publish_date> 
     <description>A deep sea diver finds true love twenty 
     thousand leagues beneath the sea.</description> 
    </book> 
    <book id="bk108"> 
     <author>Knorr, Stefan</author> 
     <title>Creepy Crawlies</title> 
     <genre>Horror</genre> 
     <price>4.95</price> 
     <publish_date>2000-12-06</publish_date> 
     <description>An anthology of horror stories about roaches, 
     centipedes, scorpions and other insects.</description> 
    </book> 
    <book id="bk109"> 
     <author>Kress, Peter</author> 
     <title>Paradox Lost</title> 
     <genre>Science Fiction</genre> 
     <price>6.95</price> 
     <publish_date>2000-11-02</publish_date> 
     <description>After an inadvertant trip through a Heisenberg 
     Uncertainty Device, James Salway discovers the problems 
     of being quantum.</description> 
    </book> 
    <book id="bk110"> 
     <author>O'Brien, Tim</author> 
     <title>Microsoft .NET: The Programming Bible</title> 
     <genre>Computer</genre> 
     <price>36.95</price> 
     <publish_date>2000-12-09</publish_date> 
     <description>Microsoft's .NET initiative is explored in 
     detail in this deep programmer's reference.</description> 
    </book> 
    <book id="bk111"> 
     <author>O'Brien, Tim</author> 
     <title>MSXML3: A Comprehensive Guide</title> 
     <genre>Computer</genre> 
     <price>36.95</price> 
     <publish_date>2000-12-01</publish_date> 
     <description>The Microsoft MSXML3 parser is covered in 
     detail, with attention to XML DOM interfaces, XSLT processing, 
     SAX and more.</description> 
    </book> 
    <book id="bk112"> 
     <author>Galos, Mike</author> 
     <title>Visual Studio 7: A Comprehensive Guide</title> 
     <genre>Computer</genre> 
     <price>49.95</price> 
     <publish_date>2001-04-16</publish_date> 
     <description>Microsoft Visual Studio 7 is explored in depth, 
     looking at how Visual Basic, Visual C++, C#, and ASP+ are 
     integrated into a comprehensive development 
     environment.</description> 
    </book> 
</catalog> 
+2

我知道你说过“使用XmlReader类”。你真的不得不使用这个类,或者你只是不知道其他人(例如XElement)。 –

+0

As @ThomasD。问,为什么要使用XmlReader?根据文档,XmlReader'表示一个读取器,它提供对XML数据的快速,非缓存,只前向访问“。如果你真的想要从根节点访问每个节点,你应该只使用类似的东西。对于你在问题中提出的问题,XPath和XDocument之类的东西更有意义。 –

+0

实际上,我已经开始使用XmlReader类来解决这个问题,因为我不知道任何其他方法。如果其他方法很容易,然后显示我。 –

我认为你可以使用LINQ对XML technique.However如果你想使用XMLReader类,你可以使用下面的代码片段

using (var inFile = new FileStream(path, FileMode.Open)) 
    { 
     using (var reader = new XmlTextReader(inFile)) 
     { 
      while (reader.Read()) 
      { 

         if (reader.NodeType == XmlNodeType.Element && reader.Name == "book" && reader.GetAttribute(0) == "bk103") 
         { 


         } 

       } 
      } 
     } 
    } 
+0

之后如何读取作者和该书籍ID的标题的价值? –

这是一个简单的实现(可以提高,当然, ):

 bool isFoundId = false; 
     string title = string.Empty; 
     string author = string.Empty; 

     using (var str = File.OpenRead("data.xml")) 
     { 
      using (XmlReader reader = new XmlTextReader(str)) 
      { 
       while (reader.Read()) 
       { 
        if (reader.Name == "book") 
        { 
         var v = reader.GetAttribute("id"); 
         if (v == "bk101") 
         { 
          isFoundId = true; 
         } 
         else if (isFoundId) 
         { 
          break; 
         } 
        } 
        if (isFoundId && reader.Name == "title") 
        { 
         title = reader.ReadElementContentAsString(); 
        } 
        if (isFoundId && reader.Name == "author") 
        { 
         author = reader.ReadElementContentAsString(); 
        } 
       } 
      } 
     } 

这就是你如何使用XPath来做到这一点。我假定你的xml在一个文件中,但你可以将任何有效的XML字符串传递给XDocument.Parse方法。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Xml.Linq; 
using System.Xml.XPath; 

namespace * 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string catalog = System.IO.File.ReadAllText("catalog.xml"); 

      System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Parse(catalog); 

      var targetBook = xdoc.XPathSelectElement("//catalog/book[@id='bk101']"); 
      var targetBookTitle = targetBook.XPathSelectElement("title").Value; 
      var targetBookAuthor = targetBook.XPathSelectElement("author").Value; 

      Console.Write($"{ targetBookTitle} - { targetBookAuthor}"); 
      Console.Read(); 

     } 
    } 
} 

对于巨大的xml文件xmlreader是最好的方法。这是我认为最好的解决方案。它使用xmlreader和xml linq的组合。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication3 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     public static void Main(string[] args) 
     { 
      new Book(FILENAME); 
     } 
    } 
    public class Book 
    { 
     public static List<Book> books = new List<Book>(); 

     string id { get; set; } 
     string title { get; set; } 
     string author { get; set; } 

     public Book() { } 
     public Book(string filename) 
     { 
      XmlReader reader = XmlReader.Create(filename); 

      while (!reader.EOF) 
      { 
       if (reader.Name != "book") 
       { 
        reader.ReadToFollowing("book"); 
       } 
       if (!reader.EOF) 
       { 
        Book newBook = new Book(); 
        books.Add(newBook); 

        XElement xmlBook = (XElement)XElement.ReadFrom(reader); 
        newBook.id = (string)xmlBook.Attribute("id"); 
        newBook.author = (string)xmlBook.Element("author"); 
        newBook.title = (string)xmlBook.Element("title"); 
       } 
      } 
     } 
    } 
} 

至于暗示,接近这将是使用LINQ to XML的最简单的方法,除非你有一个非常的XML文档。它很干净简单:

var query = 
    from book in doc.Descendants("book") 
    where (string) book.Attribute("id") == "bk101" 
    select new 
    { 
     Author = (string) book.Element("author"), 
     Title = (string) book.Element("title") 
    }; 

var result = query.Single(); 

请参阅this fiddle的演示。