Como faço para acessar os dados XML na minha coluna usando LINQ to XML?
-
03-07-2019 - |
Pergunta
Eu tenho esse XML em uma coluna na minha tabela:
<keywords>
<keyword name="First Name" value="|FIRSTNAME|" display="Jack" />
<keyword name="Last Name" value="|LASTNAME|" display="Jones" />
<keyword name="City" value="|CITY|" display="Anytown" />
<keyword name="State" value="|STATE|" display="MD" />
</keywords>
Estou recebendo um registro daquela tabela usando LINQ to SQL através deste:
GeneratedArticle ga = db.GeneratedArticles.Single(p => p.GeneratedArticleId == generatedArticleId);
que funciona, eu recebo meu objeto GeneratedArticle muito bem.
Eu gostaria de percorrer os dados no campo ArticleKeywords, que é XML. Eu comecei a fazer isso:
var keywords = from k in ga.ArticleKeywords.Elements("Keywords")
select k;
foreach (var keyword in keywords)
{
//what goes here?
}
Eu não estou 100% de certeza que eu estou recebendo os dados corretamente. Preciso de ajuda com a sintaxe apropriada para obter o valor e exibir fora do meu campo XML.
Solução
Aqui está um código de exemplo:
Para ler palavras-chave que precisamos chamada Elements ( " palavra-chave ") não Elements ( " palavras-chave ") desde palavras-chave é um nó raiz.
// IEnumerable sequence with keywords data
var keywords = from kw in ga.ArticleKeywords.Elements("keyword")
select new {
Name = (string)kw.Attribute("name"),
Value = (string)kw.Attribute("value"),
Display = (string)kw.Attribute("display")
};
foreach (var keyword in keywords)
{
var kw = "Name: " + keyword.Name +
" Value: " + keyword.Value +
" Display: " + keyword.Display;
Console.WriteLine(kw);
}
Você pode obter o valor do atributo usando foo.Attribute ( "bar"). Value , mas este método jogaria exceção se o atributo está faltando. forma segura de obter valor do atributo é (string) foo.Attribute ( "bar") - ele vai te dar nulo se o atributo está faltando
Outras dicas
Mais uma vez eu estou espantado que as pessoas nem sequer tentar as suas respostas e as pessoas ainda se voto quando eles não funcionam. Os .Elements vai ter a lista de elementos na raiz atual, que não é uma palavra-chave.
Além disso, o um usando .Attributes [ "X"] nem sequer compilar você precisa para uso () é claro, novamente, estaria operando em cada instância de "palavras-chave" não "palavra-chave"
Você pode usar
var keywords = from kw in ga.ArticleKeywords.Element("keywords").Elements()
ou
var keywords = from kw in ga.ArticleKeywords.Element("keywords").Elements("keyword")
ou (isto irá obter todos os elementos-chave, independentemente do nível)
var keywords = from kw in ga.ArticleKeywords.Descendants("keyword")
Eu acho que algo como isso iria funcionar
var keywordData = from k in ga.ArticleKeywords.Elements("Keywords")
select new { Value = k.Attributes["value"].Value,
Display = k.Attributes["display"].Value};
Isto lhe daria um IEnumerable de um tipo anônimo que contém um valor e uma propriedade Display. Dependendo do que você está fazendo, você poderia facilmente substituir o tipo anônimo com um tipo concreto.