2013-05-20 19 views
6

Próbuję uzyskać PurchaseDate z następującą strukturę XML (paragon z zakupu w aplikacji na Windows Phone):elementem Znalezienie atrybut z XDocument

<Receipt Version="1.0" CertificateId="..." xmlns="http://schemas.microsoft.com/windows/2012/store/receipt"> 
    <ProductReceipt PurchasePrice="$0" PurchaseDate="2013-05-20T19:27:09.755Z" Id="..." AppId="..." ProductId="Unlock" ProductType="Consumable" PublisherUserId="..." PublisherDeviceId="..." MicrosoftProductId="..." /> 
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> 
    <SignedInfo> 
     <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" /> 
     <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" /> 
     <Reference URI=""> 
     <Transforms> 
      <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /> 
     </Transforms> 
     <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> 
     <DigestValue>...</DigestValue> 
     </Reference> 
    </SignedInfo> 
    <SignatureValue>...</SignatureValue> 
    </Signature> 
</Receipt> 

Mój kod wygląda następująco:

XDocument doc = XDocument.Parse(receiptXml); 

string date = doc.Root.Element("ProductReceipt").Attribute("PurchaseData").Value; 

Powoduje to zwiększenie błędu dostępu, ponieważ doc.Root.Element("ProductReceipt") ma wartość null. Dlaczego XDocument nie otrzymuje elementu ProductReceipt?

Odpowiedz

8

Po prostu dodaj przestrzeń nazw do zapytania LINQ do XML. Ponieważ masz domyślną deklarację przestrzeni nazw w węźle głównym xmlns="http://schemas.microsoft.com/windows/2012/store/receipt", musisz również podać ją w zapytaniu.

Następny kod pokazuje przykład:

XDocument doc = XDocument.Parse(receiptXml); 

XNamespace xmlns = "http://schemas.microsoft.com/windows/2012/store/receipt"; 

string date = doc.Root 
       .Element(xmlns + "ProductReceipt") 
       .Attribute("PurchaseDate") 
       .Value; 

Console.WriteLine(date); 

drukuje:

2013-05-20T19:27:09.755Z 

Istnieje również nazw agnostyk podejście:

string date = doc.Root 
       .Elements() 
       .First(node => node.Name.LocalName == "ProductReceipt") 
       .Attribute("PurchaseDate") 
       .Value; 
+1

Pamiętaj, że jeśli chcesz datę jako DateTime można go uprościć do: 'var date = (DateTime) doc.Root.Element (xmlns +" ProductReceipt "). Atrybut (" PurchaseDate ");' –

+1

@MatthewWatson dzięki za uwagę. Mimo że OP konkretnie wskazał ciąg jako typ danych dla daty. Można go zmienić, jeśli chce. –

+0

Świetna i zwięzła odpowiedź! Dziękuję Ci bardzo! Uwaga @ MatthewWatson była również pomocna, dziękuję! – Filly