2017-04-24 10 views
0

WebサービスからXMLセットを取得し、XDocumentにロードして解析します。 1つのノードでは、XMLにファイルを出力すると、その属性が存在しないことがわかります。そして私は、このエラーを引き起こすために私がやっている愚かなことを理解できません。既存のノードの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 'なら、" element2 "を探しているところで' Element'を呼び出します。あなたのコードがどのようにしてこの例でもうまくいくかはわかりません。 – juharr

答えて

2

OK、そう、あなたの変数名はclsxlclxllclxlchicxulubmxyzptlk、およびlerxstです。十分に賢明。

この行は例外をスローしました。その表情の深いところで失われたどこかで、何かが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が親ループ変数である。それは「集計」です。それがあなたが望むものです。

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

私はあなたがこのコードの50%を失い、簡単に眠ることができ直感を持っていますが、私はそれが高い見積りなることができるように、少しずつの意図を引き出すためにしようとしませんでした。

すべての深刻さで、私はあなたがそれらの名前をどこから得るのか理解しています。それらはノイズではなく、XML要素名に基づいています。しかし、私はそれらをxnCollateralと呼びます。余分なタイピングはそれ自身のために支払う。非常にコンパクトな70年代のCスタイルの識別子は、VT100に80x25の文字が含まれていた場合、合理的な妥協点でしたが、今はもっと大きな画面があります。

+0

ありがとうございます!私はあなたのヒントを守り、コードを再構成しました。そして今、それはより幸せです。 – Valkyrie

0

あなたのXML文書は、デフォルトの名前空間を持っているので、すべてのナビゲーション操作は、それを使用する必要があります。ほとんどの場所で正しく実行されましたが、次のような名前空間が欠落しています。

bool bv = resx.Descendants("COLLATERAL") 
関連する問題