2011-01-21 71 views
1

這是我在XPath,XQuery和Linq上下文中處理XML的第一天,我無法讓他們爲我工作。Linq從XML中選擇屬性

我的目標是提取XML Blob中AgentGUID和PublicKey的值。我正在使用的Linq查詢如下。

 IEnumerable<string> publicKey = 
      from item in xDoc.Descendants("PublicKey") 
      select (string)item.????; 

這裏是我想要選擇從XML:

<AgentRegister xmlns="sampleURI"> 
server 
<Servername>server</Servername> 
<AgentGUID>1da3a4cf-73f2-4ee2-b8c1-cef428ad4b21</AgentGUID> 
<PublicKey>&lt;RSAKeyValue&gt;&lt;Modulus&gt;5fuiFE74EKYUxFbSsAgeYQwyGzulQ+L1auBD1J/1gupF2s2NugpgZ6vqsi4o//vKdrKz7uhwDWeRUB5TR7hljNfOsJKbTV0sg4HywF93cyYDnfKz+2wCSxiZxAIWV8SMiui2QuD0LjbgPNGR/bBsY4GIl3eWbngjJjNEzVZq5RE=&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;</PublicKey> 
<ApprovedByGUID>&lt;RSAKeyValue&gt;&lt;Modulus&gt;5fuiFE74EKYUxFbSsAgeYQwyGzulQ+L1auBD1J/1gupF2s2NugpgZ6vqsi4o//vKdrKz7uhwDWeRUB5TR7hljNfOsJKbTV0sg4HywF93cyYDnfKz+2wCSxiZxAIWV8SMiui2QuD0LjbgPNGR/bBsY4GIl3eWbngjJjNEzVZq5RE=&lt;/Modulus&gt;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;</ApprovedByGUID> 
<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/2000/09/xmldsig#rsa-sha1" /> 
<Reference URI=""> 
<Transforms> 
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /></Transforms> 
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> 
<DigestValue>2HuOAQAAxOTWz2JSq9+bJnWM8m8=</DigestValue></Reference> 
</SignedInfo> 
<SignatureValue>yGKq/p/JQCWSJtVKeRp4E5kHeFWVaoMFd/TbrYIm6k3nYBgr57gcEZjzvrLNsmKKaoaWspSqMzTDnrhER5AkfMi+4nhW0C6+vghNYU/jrEqT35Ov/B3aH1M41q07p3OXZc8dA1lzJ6Zh0zpx6Vd7faTfvuPqgIKmNOe07xGyP2Q=</SignatureValue> 
<KeyInfo><KeyValue><RSAKeyValue> 
<Modulus>5fuiFE74EKYUxFbSsAgeYQwyGzulQ+L1auBD1J/1gupF2s2NugpgZ6vqsi4o//vKdrKz7uhwDWeRUB5TR7hljNfOsJKbTV0sg4HywF93cyYDnfKz+2wCSxiZxAIWV8SMiui2QuD0LjbgPNGR/bBsY4GIl3eWbngjJjNEzVZq5RE=</Modulus> 
<Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo> 
</Signature> 
</AgentRegister> 

如何從這個文件中提取提到的值?

回答

1

我會這樣做,使用XDocument但沒有LINQ,如果你不希望文檔的一般結構改變。

var publicKey = (string)xDoc.Root.Element("PublicKey"); 
var agentGuid = (Guid)xDoc.Root.Element("AgentGUID"); 

如果你知道,只有一個給定的標籤的情況下,這是少一些麻煩,只是去把那個實例,而不是調用選擇具有指定名稱的所有標籤的方法,然後提取從單個值產生IEnumerable<>

但是,您的原始代碼幾乎是正確的。

IEnumerable<string> publicKeys = 
     from item in xDoc.Descendants("PublicKey") 
     select (string)item; 

但你不得不遵循了:

string publicKey = publicKeys.First(); 

XElement類型定義自定義轉換操作符爲許多不同的基本類型。它有一個Value屬性返回一個字符串,所以你可以使用它,如果一個字符串是你想要的 - 沒有任何強制轉換 - 但是通常只需要將一個包含值的XElement直接轉換爲你想要的數據類型就更方便了。

更新

如果你需要一個XmlDocument你可以轉換一個XDocument這樣的...

var doc = new XmlDocument(); 
doc.Load(xDoc.CreateReader()); 

但是,它可能更有效,只需使用一個XmlDocument,首先,即使它不太方便。從一個XmlDocument得到相同的價值觀的一種方法是這樣的:

var publicKey = doc.GetElementsByTagName("PublicKey")[0].InnerText; 
var agentGuid = new Guid(doc.GetElementsByTagName("AgentGUID")[0].InnerText); 
+0

這是偉大的..但我意識到,'SignedXml()`需要的XMLDocument或的XMLElement。將不可信的XML加載到多個對象中有意義嗎?更多的安全風險?我應該只嘗試在XMLDocument的範圍內工作嗎? – LamonteCristo 2011-01-21 22:16:58