我目前正在开发一个解析多个XML文件的应用程序。我同时使用了XmlDocument
和XmlReader
。这是其中一部分。
private void button5_Click(object sender, EventArgs e)
{
var filenames = System.IO.Directory
.EnumerateFiles(textBox1.Text, "*.xml", SearchOption.AllDirectories)
.Select(System.IO.Path.GetFullPath);
foreach (var f in filenames)
{
var sr = new MyStreamReader(f);
var resolver = new XmlUrlOverrideResolver();
resolver.DtdFileMap[@"XSEIF_R6.DTD"] = @"\locXSEIF_R6.DTD";
resolver.DtdFileMap[@"XSEIF_R5.DTD"] = @"\locXSEIF_R5.DTD";
resolver.DtdFileMap[@"XSEIF R5.DTD"] = @"\locXSEIF_R5.DTD";
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.XmlResolver = resolver;
XmlReader doc = XmlReader.Create(sr, settings);
while (doc.Read())
{
if ((doc.NodeType == XmlNodeType.Element) && (doc.Name == "var"))
{
if (newdoc.HasAttributes)
{
String vname = newdoc.GetAttribute("name");
String vno = newdoc.GetAttribute("number");
String pname = newdoc.GetAttribute("p-names");
File.AppendAllText(@"locaVar.txt", vname + pname + Environment.NewLine);
}
}
}
}
MessageBox.Show("Done");
}
代码没有问题。现在我想添加另一个输出。我需要添加另一个名为"title"的标签的值。该标记多次出现。但我只需要第一次出现。我知道如何在XmlDocument
中做到这一点,但正如我之前使用XmlReader
所做的那样,我想继续这样做。
如何获取第一个title标签的值?
由于您熟悉XmlDocument
,因此应该只使用XmlReader
加载XmlDocument
这可以很容易地完成(假设XmlReader
被命名为读取器):
XmlDocument doc = new XmlDocument;
doc.Load(reader);
//perform queries
唯一的问题是,您需要确保XmlReader
当前处于其初始状态,因为它是只读的,并且可能会产生意外的结果,因为假设它位于根节点,它将从读取器的当前位置加载。
此外,根据您发布的代码,您应该注意MSDN文档建议NOT使用GetElementsByTagName()
方法。相反,您应该使用SelectNodes()
或SelectSingleNode()
,它们采用XPath表达式来分别返回一个XmlNodeList
或单个XmlNode
。
编辑:OP修改了他的问题&更改了发布的代码,因为它不是完全清楚。以下是使用XmlReader
的当前问题迭代的答案:
您需要理解,与C#中的其他XML解析不同,XmlReader
是只读的。因此,您不能只在循环的末尾添加代码,因为您需要再次重读整个文档,这将是一种浪费。我建议使用一个标志和一个额外的else if
语句来执行此操作,这样您就可以在一次读取中处理所有这些。这里有一个例子:
bool notFound = true;
while (doc.Read())
{
if ((doc.NodeType == XmlNodeType.Element) && (doc.Name.Equals("var")))
{
if (newdoc.HasAttributes)
{
String vname = newdoc.GetAttribute("name");
String vno = newdoc.GetAttribute("number");
String pname = newdoc.GetAttribute("p-names");
//File.AppendAllText(@"locaVar.txt", vname + pname + Environment.NewLine);
}
}
else if(notFound && doc.NodeType == XmlNodeType.Element && doc.Name.Equals("title"))
{
notFound = false;
//do whatever you need to do here w/ this node
}
}
在上面的例子中,一旦你有了所需的所有数据,你很可能需要将你的文章移到正确的位置,这就是我注释掉的原因。另外请注意,我已将字符串比较更改为使用Equals
而不是==
。切勿使用==
进行字符串比较。