在 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 执行运算

解决方案 »

  1.   

    把ID 当作<BookOrder>的属性
    <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 ");
    相乘
      

  2.   

    用循环遍历吧, dataset才是最消耗资源的。
      

  3.   

    直接用xpath的函数sum,见:http://msdn.microsoft.com/en-us/library/ms256160.aspx
      

  4.   


    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
      

  5.   

    循环设置肯定比dataset 性能高!xml 转换成 dataset ,dataset 再转换成 xml 都很耗时
      

  6.   

    XPathExpression ,我昨晚研究了很久
    一直试验到凌晨两点半,没有成功,期待牛人。
      

  7.   

    我的方法不行吗
    获取id集合后,根据id遍历?
      

  8.   

    遍历肯定可以,楼主是想要个简单些的方法,就象SQL中的update set fld=fld1*fld2这样的。
      

  9.   

    其实lz没有必要 更新你的xml,你直接在页面输出的时候进行 计算就可以了。,
      

  10.   

    将相关字段获取到datatable 里面 之后遍历
      

  11.   

    public class XMLOP
        {
            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);
                }
            }
        }
      

  12.   

    使用linq to xml吧! 很好很强大!