使用下面的XML片段,如何使用XMLReader访问节点<amt>
的子节点<salesTaxAmt>
?如果我遍历寻找节点名称“amt”的节点,则返回<sourceCurrAmt>
的最后一个节点数量,即0.00。
<transactionUnit>
<transactionDetails>
<transactionId>11883382</transactionId>
<currencyAmount>
<amt>30.00</amt>
<currCode>USD</currCode>
</currencyAmount>
<gstAmount>
<amt>60.00</amt>
<currCode>USD</currCode>
</gstAmount>
<pstNqstAmt>
<amt>0.00</amt>
<currCode>USD</currCode>
</pstNqstAmt>
<salesTaxAmt>
<amt>1.00</amt>
<currCode>USD</currCode>
</salesTaxAmt>
<sourceCurrAmt>
<amt>0.00</amt>
</sourceCurrAmt>
</transactionDetails>
</transactionUnit>
下面的代码是否是执行此操作的最佳方法?
测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
namespace TestConsole
{
public class ParseXML
{
static void Main(string[] args)
{
try
{
FileStream file;
XmlReader baseReader;
XmlTextReader reader;
XmlReaderSettings readerSettings;
file = new FileStream(@"C:\Data.xml", FileMode.Open, FileAccess.Read);
file.Seek(0, SeekOrigin.Begin);
reader = new XmlTextReader(file, XmlNodeType.Element, null);
reader.Normalization = false;
readerSettings = new XmlReaderSettings();
readerSettings.ConformanceLevel = ConformanceLevel.Fragment;
readerSettings.IgnoreWhitespace = false;
readerSettings.IgnoreComments = true;
readerSettings.CheckCharacters = false;
baseReader = XmlReader.Create(reader, readerSettings);
int x = 0;
while (baseReader.Read())
{
if (baseReader.Name.Equals("transactionUnit") && (baseReader.NodeType == XmlNodeType.Element))
{
string amt = null;
XmlReader inner = reader.ReadSubtree();
while (inner.Read())
{
if (inner.Name.Equals("ns:amt"))
{
amt = inner.ReadElementString();
}
}
Console.WriteLine("amt: {0}", amt);
inner.Close();
x = x + 1;
}
}
Console.WriteLine("{0} transactions found", x.ToString());
baseReader.Close();
file.Close();
}
catch (XmlException xe)
{
Console.WriteLine("XML Parsing Error: " + xe);
}
catch (IOException ioe)
{
Console.WriteLine("File I/O Error: " + ioe);
}
}
}
}
答案 0 :(得分:3)
从您的示例代码看起来您可以使用LINQ to XML,这对您的问题来说是一个更简洁的解决方案:
XDocument xDoc = XDocument.Load(@"C:\Data.xml");
string amt = xDoc.Descendants("salesTaxAmt")
.Elements("amt")
.Single().Value;
如果你可以使用LINQ to XML肯定是你的选择,它提供了一种简单而强大的语法,用于从XML检索数据并与LINQ to objects很好地配合。
答案 1 :(得分:1)
获取节点值的一种更简单的方法是使用XPath。
请注意,仅当您将路径指向要检索其值的节点时,才可以执行此操作。
private string GetNodeValue(string xmlFilePath, string xpath)
{
string nodeValue = string.Empty;
using (StreamReader reader = new StreamReader(xmlFilePath))
{
XPathDocument xPathDocument = new XPathDocument(reader);
XPathNavigator navigator = xPathDocument.CreateNavigator();
XPathNodeIterator iter = navigator.Select(xpath);
iter.MoveNext();
nodeValue = iter.Current.Value;
//iter.Current.ValueAsDouble;
}
return nodeValue;
}
示例xml的用法应为:
string nodeValue = GetNodeValue(@"C:\Data.xml", "//transactionUnit/transactionDetails/salesTaxAmt/amt");
此外,您可以将该方法重命名为“GetNodeValueAsDouble”,并使用iter.Current.ValueAsDouble
代替iter.Current.Value
来获取双倍值。
更多信息