2016-10-06 11 views
0

私は、XpathとXMLの解析に関連するすべての例を掘り下げています。私はそれに対処しなければならないXMLの例を十分に見つけることができず、それは私には意味をなさない。私は特にXpathの周りを頭で囲むのは非常に困難な時間を抱えていますが、より一般的な意味でのXML解析です。私が扱っているファイルの複雑さは、理解しやすくしていません。部分的な名前空間(Xpath)を持つxmlNodeListへのアクセス

私は遠隔地からのXMLファイルを持っていますが、私はそれを制御できません。 ファイルは次のとおりです。

<AssetWarrantyDTO xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Dell.Support.AssetsExternalAPI.Web.Models.V1.Response"> 
<AdditionalInformation i:nil="true"/> 
<AssetWarrantyResponse> 
<AssetWarrantyResponse> 
<AssetEntitlementData> 
<AssetEntitlement> 
<EndDate>2010-12-20T23:59:59</EndDate> 
<EntitlementType>EXTENDED</EntitlementType> 
<ItemNumber>983-4252</ItemNumber> 
<ServiceLevelCode>ND</ServiceLevelCode> 
<ServiceLevelDescription>Next Business Day Onsite</ServiceLevelDescription> 
<ServiceLevelGroup>5</ServiceLevelGroup> 
<ServiceProvider>UNY</ServiceProvider> 
<StartDate>2008-12-21T00:00:00</StartDate> 
</AssetEntitlement> 
<AssetEntitlement> 
<EndDate>2010-12-20T23:59:59</EndDate> 
<EntitlementType>EXTENDED</EntitlementType> 
<ItemNumber>987-1139</ItemNumber> 
<ServiceLevelCode>TS</ServiceLevelCode> 
<ServiceLevelDescription>ProSupport</ServiceLevelDescription> 
<ServiceLevelGroup>8</ServiceLevelGroup> 
<ServiceProvider>DELL</ServiceProvider> 
<StartDate>2008-12-21T00:00:00</StartDate> 
</AssetEntitlement> 
<AssetEntitlement> 
<EndDate>2008-12-20T23:59:59</EndDate> 
<EntitlementType>INITIAL</EntitlementType> 
<ItemNumber>984-0210</ItemNumber> 
<ServiceLevelCode>ND</ServiceLevelCode> 
<ServiceLevelDescription>Next Business Day Onsite</ServiceLevelDescription> 
<ServiceLevelGroup>5</ServiceLevelGroup> 
<ServiceProvider>UNY</ServiceProvider> 
<StartDate>2007-12-20T00:00:00</StartDate> 
</AssetEntitlement> 
<AssetEntitlement> 
<EndDate>2008-12-20T23:59:59</EndDate> 
<EntitlementType>INITIAL</EntitlementType> 
<ItemNumber>987-1308</ItemNumber> 
<ServiceLevelCode>TS</ServiceLevelCode> 
<ServiceLevelDescription>ProSupport</ServiceLevelDescription> 
<ServiceLevelGroup>8</ServiceLevelGroup> 
<ServiceProvider>DELL</ServiceProvider> 
<StartDate>2007-12-20T00:00:00</StartDate> 
</AssetEntitlement> 
</AssetEntitlementData> 
<AssetHeaderData> 
<BUID>11</BUID> 
<CountryLookupCode>US</CountryLookupCode> 
<CustomerNumber>64724056</CustomerNumber> 
<IsDuplicate>false</IsDuplicate> 
<ItemClassCode>`U060</ItemClassCode> 
<LocalChannel>17</LocalChannel> 
<MachineDescription>Precision T3400</MachineDescription> 
<OrderNumber>979857987</OrderNumber> 
<ParentServiceTag i:nil="true"/> 
<ServiceTag>7P3VBU1</ServiceTag> 
<ShipDate>2007-12-20T00:00:00</ShipDate> 
</AssetHeaderData> 
<ProductHeaderData> 
<LOB>Dell Precision WorkStation</LOB> 
<LOBFriendlyName>Precision WorkStation</LOBFriendlyName> 
<ProductFamily>Desktops & All-in-Ones</ProductFamily> 
<ProductId>precision-t3400</ProductId> 
<SystemDescription>Precision T3400</SystemDescription> 
</ProductHeaderData> 
</AssetWarrantyResponse> 
</AssetWarrantyResponse> 
<ExcessTags> 
<BadAssets xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
</ExcessTags> 
<InvalidBILAssets> 
<BadAssets xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
</InvalidBILAssets> 
<InvalidFormatAssets> 
<BadAssets xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/> 
</InvalidFormatAssets> 
</AssetWarrantyDTO> 

ここでAPIのURLのURI変数の設定を含まない最終的なコードです。

protected void Unnamed1_Click(object sender, EventArgs e) 
{ 
    string Serial = TextBox1.Text.ToUpper(); 
    URI = String.Format(URI, Serial);   
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URI); 
    request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"; 
    request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
    CookieContainer aCookie = new CookieContainer(); 
    request.CookieContainer = aCookie; 
    WebResponse pageResponse = request.GetResponse(); 
    Stream responseStream = pageResponse.GetResponseStream();   
    string xml = string.Empty; 
    using (StreamReader streamRead = new StreamReader(responseStream)) 
    { 
     xml = streamRead.ReadToEnd();    
    } 
    XmlDocument doc1 = new XmlDocument();  
    doc1.LoadXml(xml); 
    string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); 
    if (xml.StartsWith(_byteOrderMarkUtf8)) 
    { 
     var lastIndexOfUtf8 = _byteOrderMarkUtf8.Length - 1; 
     xml = xml.Remove(0, lastIndexOfUtf8); 
     //Label2.Text = "BOM found."; 
    } 
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc1.NameTable); 
    nsmgr.AddNamespace("j", "http://schemas.datacontract.org/2004/07/Dell.Support.AssetsExternalAPI.Web.Models.V1.Response"); 
    XmlNodeList nodes = doc1.SelectNodes(".//j:AssetWarrantyResponse/j:AssetWarrantyResponse/j:AssetEntitlementData", nsmgr);  
    //Make a list to hold the start dates 
    System.Collections.ArrayList startDates = new System.Collections.ArrayList(); 
    //Make a list to hold the end dates 
    System.Collections.ArrayList endDates = new System.Collections.ArrayList(); 
    //Create a regex for finding just the date and discarding the time value which can alter tha date if the time is 24:00 (euro standard) 
    Regex r = new Regex(@"\d{4}-\d{1,2}-\d{1,2}", RegexOptions.IgnoreCase); 
    //Set the culture to format the date as US region 
    CultureInfo dtFormat = new CultureInfo("en-US", false); 
    foreach (XmlNode node in nodes) 
    { 
     foreach (XmlNode childNode in node.ChildNodes) 
     {    
     string startDate = childNode["StartDate"].InnerText; 

     if (startDate != null) 
      { 
       MatchCollection mcl1 = r.Matches(startDate); 
       startDates.Add(DateTime.Parse(mcl1[0].ToString(), dtFormat)); 
      } 

     string endDate = childNode["EndDate"].InnerText; 
     if (endDate != null) 
      { 

       MatchCollection mcl2 = r.Matches(endDate); 
       endDates.Add(DateTime.Parse(mcl2[0].ToString(), dtFormat)); 
      } 
     } 
     startDates.Sort(); 
     endDates.Sort(); 
     DateTime wStartDate = new DateTime(); 
     DateTime wEndDate = new DateTime(); 
     //if (dates.Count > 1) wStartDate = (DateTime)dates[dates.Count - 1]; 
     if (startDates.Count >= 1) wStartDate = (DateTime)startDates[0]; 
     Label1.Text = wStartDate.ToString("MM/dd/yyyy"); 
     if (endDates.Count >= 1) wEndDate = (DateTime)endDates[endDates.Count - 1]; 
     Label2.Text = wEndDate.ToString("MM/dd/yyyy"); 
     //Label2.Text = tempc; 
     //Label3.Text = feels; 
    } 
    nodes = doc1.SelectNodes(".//j:AssetWarrantyResponse/j:AssetWarrantyResponse/j:AssetHeaderData", nsmgr); 
    foreach (XmlNode node in nodes) 
    { 
     try 
     { 
      string custNumber = node["CustomerNumber"].InnerText; 
      string model = node["MachineDescription"].InnerText; 
      string orderNumber = node["OrderNumber"].InnerText; 
      string serialNumber = node["ServiceTag"].InnerText; 
      Label3.Text = custNumber; 
      Label4.Text = model; 
      Label5.Text = orderNumber; 
      Label6.Text = serialNumber; 

     } 
     catch (Exception ex) 
     { 
      dbgLabel.Text = ex.Message; 
     } 
    } 
} 

答えて

0

あなたは、名前空間http://www.w3.org/2001/XMLSchema-instance(あなたが「i」の接頭辞にバインドされている名前空間)にAssetWarrantyResponseを探しているが、それは名前空間http://schemas.datacontract.org/2004/07/Dell.Support.AssetsExternalAPI.Web.Models.V1.Responseに実際にあります。その名前空間にプレフィックスをバインドし(例: "p"など)、そのプレフィックスをクエリに使用します。 p:AssetWarrantyResponseであり、他の要素名についても同様である。

あなたがやりたいこととまったく同じサンプルコードを探すのに時間がかかり過ぎ、自分の問題にそれらを適用できるように、言語の基礎概念を勉強する時間が足りません。いくつかの良いXMLブックを入手し、それらを読んでください。

XPathには、パスの最後にある「/」という別の問題があります。それは無効な構文です。これがエラーの原因なら、私はXPathプロセッサの診断にはそれほど感心しません。

+0

"式はノードセットに評価されなければなりません"エラー:.Netは無効なXPathが '/'で終わるため生成されます(技術的には正解ですが参考にならない) - http://stackoverflow.com/questions/17839989/expressionノード集合を評価する必要がある)。 –

+0

上記の両方の応答の提案を適用すると、このエラーが表示されます。名前空間マネージャまたはXsltContextが必要です。このクエリには、接頭辞、変数、またはユーザー定義関数があります。変更を反映するために元の投稿を編集しました。 – user1431356

+0

Xpath文字列の問題を部分的に過ぎました。 xpathは正しくishですが、StartDate要素はnullを返しています。コード現在の変更を反映するように編集されました。 – user1431356

関連する問題