I'm trying to get the PurchaseDate from the following XML structure (a receipt from an in-app purchase in Windows Phone):
<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>
My code goes as follows:
XDocument doc = XDocument.Parse(receiptXml);
string date = doc.Root.Element("ProductReceipt").Attribute("PurchaseData").Value;
This keeps raising an access error, because doc.Root.Element("ProductReceipt")
is null. Why is XDocument not getting the ProductReceipt element?
Search elements by attribute First, you can fetch an element's attribute by using XElement. Attribute(name). Then you can look at its value by using the . Value property.
If you are getting the value and the attribute might not exist, it is more convenient to use the explicit conversion operators, and assign the attribute to a nullable type such as string or Nullable<T> of Int32 . If the attribute does not exist, then the nullable type is set to null.
The XElement class is one of the fundamental classes in LINQ to XML. It represents an XML element. The following list shows what you can use this class for: Create elements. Change the content of the element.
Just add namespace to your LINQ to XML query. Because you have default namespace declaration at the root node xmlns="http://schemas.microsoft.com/windows/2012/store/receipt"
you also need to specify it in your query.
Next code shows an example:
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);
prints:
2013-05-20T19:27:09.755Z
There is also a namespace agnostic approach:
string date = doc.Root
.Elements()
.First(node => node.Name.LocalName == "ProductReceipt")
.Attribute("PurchaseDate")
.Value;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With