在 ASP.NET(C#) 开发过程中,我用 XML 进行数据的收集与传输,需要对其两节点进行运算,如:<Root>
<BookOrder>
<ID>1</ID>
<Name>书名一</Name>
<Number>4</Number>
<Price>25.00</Price>
<TolalAmount></TolalAmount>
<Re />
</BookOrder>
<BookOrder>
<ID>1</ID>
<Name>书名二</Name>
<Number>6</Number>
<Price>30.50</Price>
<Re />
</BookOrder>
</Root>如何对上述 XML 进行运算,得到相应的 TolalAmount,我能够想到的有两种方法。一、用循环更新
System.Xml.XmlDocument x_doc = new System.Xml.XmlDocument();
x_doc.LoadXml(xml);
System.Xml.XPath.XPathNavigator x_pn = x_doc.CreateNavigator();
System.Xml.XPath.XPathNodeIterator x_ni = xpn.Select("BookOrder//TolalAmount");
System.Xml.XPath.XPathNavigator x_tol, x_pri,x_num;
while (x_ni.MoveNext())
{
x_tol = x_ni.Current;
x_num = xpn.SelectSingleNode("BookOrder[position()=" + xni.CurrentPosition.ToString() + "]//Number);
x_pri = xpn.SelectSingleNode("BookOrder[position()=" + xni.CurrentPosition.ToString() + "]//Price); x_tol.SetValue((x_num.ValueAsDouble * x_pri.ValueAsDouble).ToString());
}二、转换成 DataSet,设置 DataColumn.Expression ,然后再转回 xml System.IO.StringReader sr = new System.IO.StringReader(xml);
DataSet ds = new DataSet();
ds.ReadXml(sr);
ds.Tables["BookOrder"].Columns["TolalAmount"].Expression = "Convert(Number, 'System.Decimal') * Convert(Number, 'System.Decimal')"; ds.GetXml();第一种方法,效率可能不是很高,但不会出错;
第二种方法,有个比较大的麻烦就是 转回 xml 时,发现 <Re /> 节点没有了,原因是对于某行的值为 Null 的字段,执行 DataSet.GetXml 方法后,会省略该节点。(我使用的是 VS.Net 2005)欢迎大家写出更好的办法,直接对 XML 执行运算
<BookOrder>
<ID>1</ID>
<Name>书名一</Name>
<Number>4</Number>
<Price>25.00</Price>
<TolalAmount></TolalAmount>
<Re />
</BookOrder>
<BookOrder>
<ID>1</ID>
<Name>书名二</Name>
<Number>6</Number>
<Price>30.50</Price>
<Re />
</BookOrder>
</Root>如何对上述 XML 进行运算,得到相应的 TolalAmount,我能够想到的有两种方法。一、用循环更新
System.Xml.XmlDocument x_doc = new System.Xml.XmlDocument();
x_doc.LoadXml(xml);
System.Xml.XPath.XPathNavigator x_pn = x_doc.CreateNavigator();
System.Xml.XPath.XPathNodeIterator x_ni = xpn.Select("BookOrder//TolalAmount");
System.Xml.XPath.XPathNavigator x_tol, x_pri,x_num;
while (x_ni.MoveNext())
{
x_tol = x_ni.Current;
x_num = xpn.SelectSingleNode("BookOrder[position()=" + xni.CurrentPosition.ToString() + "]//Number);
x_pri = xpn.SelectSingleNode("BookOrder[position()=" + xni.CurrentPosition.ToString() + "]//Price); x_tol.SetValue((x_num.ValueAsDouble * x_pri.ValueAsDouble).ToString());
}二、转换成 DataSet,设置 DataColumn.Expression ,然后再转回 xml System.IO.StringReader sr = new System.IO.StringReader(xml);
DataSet ds = new DataSet();
ds.ReadXml(sr);
ds.Tables["BookOrder"].Columns["TolalAmount"].Expression = "Convert(Number, 'System.Decimal') * Convert(Number, 'System.Decimal')"; ds.GetXml();第一种方法,效率可能不是很高,但不会出错;
第二种方法,有个比较大的麻烦就是 转回 xml 时,发现 <Re /> 节点没有了,原因是对于某行的值为 Null 的字段,执行 DataSet.GetXml 方法后,会省略该节点。(我使用的是 VS.Net 2005)欢迎大家写出更好的办法,直接对 XML 执行运算
<BookOrder ID=1>
<Number>4</Number>
<Price>25.00</Price>
</BookOrder>
之后
根据ID 用循环 遍历BookOrder 获取Number Price 就很方便额,
XmlNode node=xmlDoc.SelectSingleNode("Root/BookOrder[@Id='"+id+"']");
之后 获取的node 得出Number Price
XmlNode Number = node.SelectSingleNode("Number ");
XmlNode Price = node.SelectSingleNode("Price ");
相乘
String xml = @"
<Root>
<BookOrder>
<ID>1</ID>
<Name>书名一</Name>
<Number>4</Number>
<Price>25.00</Price>
<TolalAmount></TolalAmount>
<Re />
</BookOrder>
<BookOrder>
<ID>1</ID>
<Name>书名二</Name>
<Number>6</Number>
<Price>30.50</Price>
<Re />
</BookOrder>
</Root>
";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XPathNavigator navigator = doc.CreateNavigator();
String expression = "sum(/Root/BookOrder/Price)";
Console.Write(navigator.Evaluate(expression));结果:55.5
一直试验到凌晨两点半,没有成功,期待牛人。
获取id集合后,根据id遍历?
{
string data = @"<Root>
<BookOrder>
<ID>1</ID>
<Name>书名一</Name>
<Number>4</Number>
<Price>25.00</Price>
<TolalAmount>1</TolalAmount>
<Re />
</BookOrder>
<BookOrder>
<ID>1</ID>
<Name>书名一</Name>
<Number>4</Number>
<Price>25.00</Price>
<TolalAmount>2</TolalAmount>
<Re />
</BookOrder>
<BookOrder>
<ID>1</ID>
<Name>书名二</Name>
<Number>6</Number>
<Price>30.50</Price>
<Re />
</BookOrder>
</Root>"; public void GetTotalAmount()
{
XElement _data=XElement.Parse(data);
//Console.WriteLine(_data.ToString());
var TolalAmountLst = from TolalAmounts in _data.Elements().Elements("TolalAmount")
select TolalAmounts;
Console.WriteLine("TolalAmounts:");
foreach (var e in TolalAmountLst)
{
Console.WriteLine(e.Value);
}
}
}