如何使用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>
答
我认为你可以使用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 StackOverflow
{
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的演示。
我知道你说过“使用XmlReader类”。你真的不得不使用这个类,或者你只是不知道其他人(例如XElement)。 –
As @ThomasD。问,为什么要使用XmlReader?根据文档,XmlReader'表示一个读取器,它提供对XML数据的快速,非缓存,只前向访问“。如果你真的想要从根节点访问每个节点,你应该只使用类似的东西。对于你在问题中提出的问题,XPath和XDocument之类的东西更有意义。 –
实际上,我已经开始使用XmlReader类来解决这个问题,因为我不知道任何其他方法。如果其他方法很容易,然后显示我。 –