2012-10-27 80 views
1

我正在尝试编写一个程序,该程序将接收来自Web服务的输入并选择正确的信息以及订单ID。因为它是必需的,所以我使用xPath。例如,如果我在运行程序时在OrderID下输入1,它应该为该订单提取总成本并显示它。我知道我的代码肯定有什么问题,因为我是新手,我不知道如何在物理上抓住输入,而不控制所使用的变量。任何帮助将不胜感激,谢谢!如何从web服务获得输入

这里是我的代码:

[WebMethod] 
public int GetTotalCostForAnOrder(int OrderID) 
{ 
    XPathNavigator nav; 
    XPathDocument docNav; 
    XPathNodeIterator NodeIter; 

    String rootPath = Server.MapPath("~"); 
    string strFilename = rootPath + "\\OrderInfoLab3.xml"; 
    docNav = new XPathDocument(strFilename); 

    // Create a navigator to query with XPath. 
    nav = docNav.CreateNavigator(); 
    String searchString = "sum(OrderFeed/Order/Items/Item/TotalCost)"; 

    // you need to determine the proper XPath statement 

    // Select the node and place the results in an iterator. 
    NodeIter = nav.Select(searchString); 

    while (NodeIter.MoveNext()) 
    { 
     NodeIter.Current.Select("OrderID"); 
    } 

    var totalOrder = nav.Compile(searchString); 
    return Convert.ToInt32(nav.Evaluate(totalOrder)); 
} 

这里是我的XML文件:

<Order id="1"> 
<BillingInformation> 
    <Name>Bruce Ganek</Name> 
    <Address>99 Main Street</Address> 
    <City>Cranston</City> 
    <State>RI</State> 
    <ZipCode>02910</ZipCode> 
</BillingInformation> 
<ShippingInformation> 
    <Name>Governor Chafee</Name> 
    <Address>82 Smith St # 115</Address> 
    <City>Providence</City> 
    <State>RI</State> 
    <ZipCode>02903-1121</ZipCode> 
</ShippingInformation> 
<Items> 
    <Item> 
     <PartNo>JETSWEATER</PartNo> 
     <Description>N.Y. Jets Sweatshirt</Description> 
     <UnitPrice>10.50</UnitPrice> 
     <Quantity>2</Quantity> 
     <TotalCost>21.00</TotalCost> 
     <CustomerOptions> 
      <Size>M</Size> 
      <Color>Green</Color> 
     </CustomerOptions> 
    </Item> 
    <Item> 
     <PartNo>JETSWEATER</PartNo> 
     <Description>N.Y. Jets Sweatshirt</Description> 
     <UnitPrice>7.50</UnitPrice> 
     <Quantity>3</Quantity> 
     <TotalCost>22.50</TotalCost> 

     <CustomerOptions> 
      <Size>S</Size> 
      <Color>White</Color> 
     </CustomerOptions> 
    </Item> 
    <Item> 
     <PartNo>JETSFLASHLIGHT</PartNo> 
     <Description>N.Y. Jets Flashlight</Description> 
     <UnitPrice>5.00</UnitPrice> 
     <Quantity>1</Quantity> 
     <TotalCost>5.00</TotalCost> 

     <CustomerOptions/> 

    </Item> 

</Items> 
</Order> 

这是我在输出时出现错误:

System.Xml.XPath.XPathException: Expression must evaluate to a node-set. 
at System.Xml.XPath.XPathNavigator.Select(XPathExpression expr) 
at System.Xml.XPath.XPathNavigator.Select(String xpath) 
at Lab3.Service1.GetTotalCostForAnOrder(Int32 OrderID) in C:\ 
+0

你的方法返回一个int..it应该是小数 – Anirudha

回答

1

您应该使用LINQ2XML

public decimal GetTotalCostForAnOrder(int OrderID) 
{ 
    XElement doc=XElement.Load("c:\\yourXML.xml"); 
    decimal totalPrice=doc.DescendantsAndSelf("Order") 
    .Where(x=>x.Attribute("id").Value==OrderID) 
    .Select(y=>y.Element("Items")).Elements("Item") 
    .Select(z=>decimal.Parse(z.Element("TotalCost").Value)).ToList().Sum(); 
    return totalPrice; 
} 
+0

感谢您的帮助,这似乎是一种更简单的方式来遍历我的XML文件,而无需使用定义的路径。我唯一的问题是我想返回一个订单的所有项目的字符串(仍然由OrderID)。我尝试在'y'变量行的末尾添加.ToList(),然后返回,但由于某种原因它只返回列表对象本身的一个实例。有什么建议么? – nate00234

+0

'System.Collections.Generic.List'1 [System.Xml.Linq.XElement]' – nate00234

+0

@ nate00234如果你想要所有的值的顺序int一个字符串使用'y => y.Element(“Items”))。元素( “项目”)。Value' – Anirudha

2

出现以下行不正确:

String searchString = "sum(OrderFeed/Order/Items/Item/TotalCost)"; 

这应该是用于选择节点的XPath表达式,但XML中没有OrderFeed节点 - 根节点为Order

这应该带来更好的结果的节点集合:

String searchString = "/Order/Items/Item/TotalCost"; 
+0

不过,如果该选择总结每个项目在评估时的总成本值? – nate00234

+0

@华丽 - 不,它不会。但你首先需要找到正确的路径。 – Oded

+0

我的错我忘了添加根节点,它实际上确实以OrderFeed开头 – nate00234