2014-12-20 5 views
3

아래의 XML 스 니펫은 훨씬 더 큰 XML의 일부입니다. 나는 주소 1, 2, 3 및 도시와 주, 우편 번호 및 국가를 얻기 위해 계속해서 노력해 왔습니다. 내가 이것을 구체화 할 수 있도록 기능화하고 싶습니다. 그러나 InvoiceHeader id = "XXXX"를 기반으로하는 주소이지만 벽을 계속 뛰어 다니고 있습니다. 아래의 쿼리를 사용하여 줄을 따라 가봤지만 오류가 계속 발생합니다. 개체 참조가 개체 인스턴스로 설정되지 않았습니다.Linq를 XML로 가져 오기 xml 부분 검색

여기 내 검색어입니다 누군가 내 명백한 실수를 지적하시기 바랍니다 수 있습니다.

IEnumerable<string> partNos = 
      from item in PurchaseOrderXml.Descendants("RemitTo").Descendants("Address") 
      where (string)item.Attribute("id").Value == "23951768" 
      select (string)item; 



<Invoice> 
    <InvoiceHeader id="23951768" status="InProcess"> 
     <InvoiceName /> 
     <InvoiceNumber>23951768</InvoiceNumber> 
     <InvoiceDate>2014-09-26 00:00:00.0</InvoiceDate> 
     <DueDate>2014-10-26 00:00:00.0</DueDate> 
     <SupplierInvoiceNo>534254504</SupplierInvoiceNo> 
     <InvoiceType>Invoice</InvoiceType> 
     <Supplier id="3825405"> 
     <ContactInfo type="main"> 
       <Address> 
       <AddressLine lineNumber="1">Post </AddressLine> 
       <AddressLine lineNumber="2">30 Street</AddressLine> 
       <AddressLine lineNumber="3">30 Street</AddressLine> 
       <City>Saint Louis</City> 
       <State>MO</State> 
       <PostalCode>63103-2530</PostalCode> 
       <Country isoCountryCode="US">United States</Country> 
      </Address> 
     </ContactInfo> 
    </Supplier> 
     <BillTo> 
     <Address> 
      <AddressLine lineNumber="1">vvvv</AddressLine> 
      <AddressLine lineNumber="2">vvvv</AddressLine> 
      <City>Philadelphia</City> 
      <State>PA</State> 
      <PostalCode>19222</PostalCode> 
      <Country isoCountryCode="US">United States</Country> 
     </Address> 
      </BillTo> 
     <RemitTo> 
      <Address> 
       <AddressLine lineNumber="1">P O BOX 535182</AddressLine> 
       <AddressLine lineNumber="2" /> 
       <AddressLine lineNumber="3" /> 
       <City>ATLANTA</City> 
       <State>GA</State> 
       <PostalCode>303535182</PostalCode> 
       <Country isoCountryCode="US">United States</Country> 
      </Address> 
     </RemitTo> 
    </InvoiceHeader> 
</Invoice> 

답변

3

귀하의 항목 범위 변수는 id 속성이없는 주소 요소에 해당한다. 대신, 먼저 적절한 InvoiceHeader를 찾거나 필터링 한 다음 쿼리와 일치하는 InvoiceHeader의 Address 요소를 찾으십시오.

var Header = PurchaseOrderXml.Descendants("InvoiceHeader") 
.FirstOrDefault(header => (string)header.Attribute("id").Value == headerId); 

머리글이 발견되면 당신은 확인할 수 있습니다 (Header != null) : 여기

는 InvoiceHeader를 찾는 예입니다. 헤더를 얻은 후에는 해당 요소의 범위 내에서 필요한 모든 작업을 수행하십시오. 예 :

var RemitToAddress = Header.Descendants("RemitTo").Descendants("Address").FirstOrDefault(); 

당신은 헤더에 다른 요소를 검사하려면, 그래서 이런 부분으로 쿼리를 분할하는 것은 당신의 의도를 명확 유지 수 있습니다.

또한 Descendants을 사용했음을 유의하십시오. 그러나 스키마가 더 잘 일치하는 경우 Elements을 사용할 수도 있습니다.

또 다른 예는 AddressLine 요소를 얻을 그들을 연결하는, 당신의 라인을 따라 뭔가 시도 할 수 있습니다 :

IEnumerable<string> AddressLines = RemitToAddress.Elements("AddressLine") 
.OrderBy(line => (int)line.Attribute("lineNumber")) 
.Select(line => line.Value); 

var AddressText = string.Join("\n", AddressLines); 
+0

그래서 두 건의 질의가 필요합니까? – Miguel

+0

예제를 제공하기 위해 업데이트 하겠지만 개념적으로는 두 개의 쿼리가 필요합니다. –

+0

예를 들어 주시면 감사하겠습니다. 나는 물고기를 배우려고 노력하고있다 : - D. – Miguel

1

이 시도 : -

var result = xdoc.Root.Descendants("InvoiceHeader") 
    .Where(x => x.Attribute("id").Value == "23951768") 
    .SelectMany(x => x.Descendants("Address")) 
    .Select(x => 
    { 
     { 
     var addressLine1 = x.Elements("AddressLine") 
         .FirstOrDefault(z => z.Attribute("lineNumber").Value == "1"); 
     var addressLine2 = x.Elements("AddressLine") 
         .FirstOrDefault(z => z.Attribute("lineNumber").Value == "2"); 
     var addressLine3 = x.Elements("AddressLine") 
         .FirstOrDefault(z => z.Attribute("lineNumber").Value == "3"); 
     return new 
     { 
      AddressLine1 = addressLine1 != null ? addressLine1.Value : String.Empty, 
      AddressLine2 = addressLine2 != null ? addressLine1.Value : String.Empty, 
      AddressLine3 = addressLine3 != null ? addressLine1.Value : String.Empty, 
      City = x.Element("City").Value, 
      State = x.Element("State").Value 
      PostalCode = x.Element("PostalCode").Value, 
      Country= x.Element("Country").Value, 
      }; 
     } 
    }); 
+0

이 내가 위에서 게시 된 작은 XML로 작동하는 것 같다을하지만 난 문제가 있어요 원본 xml. 내가 얻을 오류 시퀀스가 ​​일치하는 요소가 포함되어 있습니다? 어떤 아이디어? – Miguel

+0

큰 XML에서 다른 모든 요소는 이와 비슷합니까? 나는 당신이'RemitTo' 노드에서'Address'를 여러개 사용할 수 있다고 생각했습니다. 시퀀스에 요소가 없습니다. 전달 된 조건과 일치하는 요소가 없습니다. 디버그하여 알려주세요. –

+0

내 큰 xml에 여러 개의 주소가 있습니다. 관련 게시물을 더 관련성이 높은 예제로 업데이트했습니다. 나는 여러 주소가 linq 쿼리 브레이크를 만드는 것일 수도 있다고 생각하십니까? – Miguel