2017-04-24 75 views
0

我從Web服務中提取XML集,將其加載到XDocument中,然後解析出來。在一個節點上,如果我將XML輸出到一個文件,那麼該屬性是CLEARLY,它告訴我它不存在。我無法弄清楚我正在做什麼愚蠢的事情導致這個錯誤。現有節點的XDocument屬性不存在

<?xml version="1.0" encoding="utf-8"?> 
<MESSAGE xmlns="http://www.mismo.org/residential/2009/schemas_v1_4_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<DEAL_SETS> 
    <DEAL_SET> 
     <DEALS> 
      <DEAL> 
       <ASSETS> 
        <OWNED_PROPERTIES> 
         <OWNED_PROPERTY SequenceNumber="1"> 
          <OWNED_PROPERTY_DETAIL> 
           <PropertyUsageType>PrimaryResidence</PropertyUsageType> 
          </OWNED_PROPERTY_DETAIL> 
         </OWNED_PROPERTY> 
         <OWNED_PROPERTY SequenceNumber="2"> 
          <OWNED_PROPERTY_DETAIL> 
           <PropertyUsageType>PrimaryResidence</PropertyUsageType> 
          </OWNED_PROPERTY_DETAIL> 
         </OWNED_PROPERTY> 
        </OWNED_PROPERTIES> 
       </ASSETS> 
       <COLLATERALS> 
        <COLLATERAL SequenceNumber="1"> 
         <COLLATERAL_DETAIL> 
          <LienPriorityExceptionType>FirstLien</LienPriorityExceptionType> 
         </COLLATERAL_DETAIL> 
         <PROPERTIES> 
          <PROPERTY> 
           <FLOOD_DETERMINATION> 
            <FLOOD_DETERMINATION_DETAIL/> 
           </FLOOD_DETERMINATION> 
           <IMPROVEMENT> 
            <UNIT_GROUPS> 
             <UNIT_GROUP> 
              <UNIT_GROUP_DETAIL> 
               <UnitType>UnitOne</UnitType> 
              </UNIT_GROUP_DETAIL> 
              <ROOM_TYPE_SUMMARY/> 
             </UNIT_GROUP> 
            </UNIT_GROUPS> 
           </IMPROVEMENT> 
          </PROPERTY> 
         </PROPERTIES> 
        </COLLATERAL> 
        <COLLATERAL SequenceNumber="5"> 
         <COLLATERAL_DETAIL> 
          <LienPriorityExceptionType>FirstLien</LienPriorityExceptionType> 
         </COLLATERAL_DETAIL> 
         <PROPERTIES> 
          <PROPERTY> 
           <FLOOD_DETERMINATION> 
            <FLOOD_DETERMINATION_DETAIL/> 
           </FLOOD_DETERMINATION> 
           <IMPROVEMENT> 
            <UNIT_GROUPS> 
             <UNIT_GROUP> 
              <UNIT_GROUP_DETAIL> 
               <UnitType>UnitOne</UnitType> 
              </UNIT_GROUP_DETAIL> 
              <ROOM_TYPE_SUMMARY/> 
             </UNIT_GROUP> 
            </UNIT_GROUPS> 
           </IMPROVEMENT> 
          </PROPERTY> 
         </PROPERTIES> 
        </COLLATERAL> 
       </COLLATERALS> 
      </DEAL> 
      </DEALS> 
     </DEAL_SET> 
    </DEAL_SETS> 
    </MESSAGE> 

我的代碼可以找到OWNED_PROPERTY就好了的SequenceNumber值,但對抵押品炸燬:

using System.Xml; 
using System.Xml.Linq; 
using System.Linq; 
using System.Net.Http; 
using System.Net.Http.Headers; 
using System.Collections.Generic; 

XDocument resx = new XDocument(); 

public override void MethodInternal() 
{ 
    string uid = "something"; 
    string pwd = "somethingelse"; 
    string httppath = "url"; 

    try 
    { 
    NetworkCredential cred = new NetworkCredential(uid, pwd); 
    CredentialCache credCache = new CredentialCache(); 
    credCache.Add(new Uri(httppath), "NTLM", cred); 
    WebRequest client = WebRequest.Create(httppath); 

    client.Credentials = credCache; 
    client.Method = "GET"; 
    client.ContentType = "application/xml"; 

    WebResponse resp = client.GetResponse(); 
    Stream respStream = resp.GetResponseStream(); 
    StreamReader strrdr = new StreamReader(respStream); 
    string allxml = strrdr.ReadToEnd(); 

    byte[] byteArray = Encoding.UTF8.GetBytes(fullstr); 

    XNamespace ns = "http://www.mismo.org/residential/2009/schemas_v1_4_2"; 
    resx = XDocument.Parse(allxml); 
    strrdr.Close(); 
    respStream.Close(); 
    resp.Close(); 

    int seqnum = 0; 
    int cseqnum = 0; 

     foreach (XElement b in resx.Root.Descendants(ns + "DEAL")) 
     { 
      // Primary node: ASSETS 
      if (b.Elements(ns + "ASSETS").Any()) 
      { 
       IEnumerable<XElement> axl = b.Descendants(ns + "ASSETS"); 
       foreach (var axcol in axl.Elements()) 
       { 
        seqnum = 0; 
        IEnumerable<XElement> opxl = b.Descendants(ns + "OWNED_PROPERTY"); 
        foreach (var opxlcol in axl.Elements()) 
        { 
         seqnum = int.Parse(opxlcol.Element(ns + "OWNED_PROPERTY").Attribute("SequenceNumber").Value.ToString()); 

         IEnumerable<XElement> opxls = opxlcol.Descendants(ns + "OWNED_PROPERTY"); 
         foreach (var opxlsc in opxls.Elements()) 
         { 
          if (opxlsc.Elements(ns + "PropertyUsageType").Any()) 
           //occa.Add(seqnum, opxlsc.Element(ns + "PropertyUsageType").Value.ToString()); 
         } 
        } // OWNED_PROPERTY XElements 
       } // XElements under ASSETS 
      } // test to make sure ASSETS exists 

      // Primary node: COLLATERALS 
      if (b.Elements(ns + "COLLATERALS").Any()) 
      { 
       IEnumerable<XElement> colsxl = b.Descendants(ns + "COLLATERALS"); 
       foreach (var clsxl in colsxl.Elements()) 
       { 
        cseqnum = 0; 
        IEnumerable<XElement> clxl = clsxl.DescendantsAndSelf(ns + "COLLATERAL"); 
        foreach (var clxll in clxl.Elements()) 
        { 
         //System.Windows.Forms.MessageBox.Show(ns.ToString() + clsxl.Name.LocalName.ToString()); 
         //if (clsxl.Name.LocalName.ToString() == "COLLATERAL") 
         //{ 
         bool bv = resx.Descendants("COLLATERAL").Select(x => (int?)x.Attribute("SequenceNumber")).FirstOrDefault(x => x != null) > 0; 
          System.Windows.Forms.MessageBox.Show(bv.ToString()); 
          System.Windows.Forms.MessageBox.Show(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString()); 
          cseqnum = int.Parse(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString()); 
         //} 

         if (clxll.Elements(ns + "LienPropertyExceptionType").Any()) 
          //liena.Add(cseqnum, clxll.Element(ns + "LienPropertyExceptionType").Value.ToString()); 

         IEnumerable<XElement> pxl = clsxl.Descendants(ns + "PROPERTY"); 
         foreach (var p in pxl.Elements()) 
         { 
          if (p.Elements(ns + "IMPROVEMENT").Any()) 
          { 
           IEnumerable<XElement> ig = p.Descendants(ns + "IMPROVEMENT"); 
           foreach (var igxl in ig.Elements()) 
           { 
            if (igxl.Elements(ns + "UnitType").Any()) 
             //nua.Add(cseqnum, igxl.Element(ns + "UnitType").Value.ToString()); 
            //} // XElements under UNIT_GROUP_DETAIL 
           } // XElements under IMPROVEMENT 
          } // test to make sure IMPROVEMENT exists 
         } // XElements under PROPERTY 
        } // XElements in COLLATERAL 
       } // XElements under COLLATERALS 
      } // test to make sure COLLATERALS exists 
     } // root 
    } 
    catch (Exception ex) 
    { 
    //handle exception 
    } 
} 

所以我要去哪裏錯了?除了XML中的文本以外,唯一不同的是OWNED_PROPERTY標籤位於附加標籤​​下,而直接位於下方。但正如你所看到的,我的代碼正在跳過標籤,因爲它對我的目的沒用。

+2

您使用命名空間中的代碼,但您的樣品不使用任何人;用一個更真實的例子可能會更容易發現問題。 –

+3

你似乎也不明白'。Descendants()會搜索節點下的整個樹,而不僅僅是下一個元素。大部分代碼是非常不必要的 – Jonesopolis

+0

'fxl'應該是所有的「element2的」元素的集合,但你在你的foreach調用'Elements'上,基本上讓「element2的」元素的所有孩子培養成'elfx ',那麼你就調用'Element'來尋找一個「element2」。我沒有看到你的代碼如何與這個例子一起工作。 – juharr

回答

2

好了,你的變量名是clsxlclxllclxlchicxulubmxyzptlklerxst。足夠明智。

此行引發異常。某處失去了表達的深度,某些東西返回null。那麼,你不能通過在MessageBox.Show()的調用的父類之間粘貼整個事件來調試,因爲整個問題是拋出異常而不是返回值。

//System.Windows.Forms.MessageBox.Show(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString()); 
cseqnum = int.Parse(clsxl.Element(ns + "COLLATERAL").Attribute("SequenceNumber").Value.ToString()); 

這就是你要做的:把它分解成最簡單的表達式,看看什麼返回什麼。花了一段時間,但是閱讀所有那些呻吟變量聲明的人的評論也是如此。

var element = clsxl.Element(ns + "COLLATERAL"); 

var attr = element.Attribute("SequenceNumber"); 

// attr.Value is already a string. If it's anything. 
cseqnum = int.Parse(attr.Value); 

在這些行的第一行上設置一個斷點,並將鼠標懸停在所有內容上。你會發現clsxl是「COLLATERAL」。它沒有帶「SequenceNumber」屬性的名爲「COLLATERAL」的孩子。 它有有「SequenceNumber」屬性。

// Ain't no such animal 
var element = clsxl.Element(ns + "COLLATERAL"); 

clsxl是父循環變量。這是「COLLATERAL」。那是你想要的。

var attr = clsxl.Attribute("SequenceNumber"); 
cseqnum = int.Parse(attr.Value); 

我有一種預感,你可能會失去這個代碼的50%和睡覺更容易,但我並沒有試圖梳理出一點一滴的意圖,所以這可能是一個高的估計。

我非常認真地理解你從哪裏得到這些名字。它們不是噪音,它們基於XML元素名稱。但是,我會打電話給他們xnCollateral等等。額外的打字支付自己。當我們在VT100上有80x25個字符時,那些非常緊湊的70年代C風格標識符是一個合理的折衷方案,但現在我們都有了更大的屏幕。

+0

謝謝你!我遵循你的提示並重構了代碼,現在更快樂了。 – Valkyrie

0

您的XML文檔有一個默認的命名空間,所以所有的導航操作都必須使用它。你就在大多數地方完成,但是你錯過了在線路的命名空間,如:

bool bv = resx.Descendants("COLLATERAL")