¿Cómo accedo a los datos XML en mi columna usando LINQ to XML?
-
03-07-2019 - |
Pregunta
Tengo este XML en una columna de mi tabla:
<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>
Estoy obteniendo un registro de esa tabla usando LINQ to SQL a través de esto:
GeneratedArticle ga = db.GeneratedArticles.Single(p => p.GeneratedArticleId == generatedArticleId);
Eso funciona, obtengo mi objeto GeneratedArticle bien.
Me gustaría recorrer los datos en el campo ArticleKeywords, que es XML. Comencé a hacer esto:
var keywords = from k in ga.ArticleKeywords.Elements("Keywords")
select k;
foreach (var keyword in keywords)
{
//what goes here?
}
No estoy 100% seguro de que estoy obteniendo los datos correctamente. Necesito ayuda con la sintaxis adecuada para obtener el valor y mostrar mi campo XML.
Solución
Aquí hay un código de ejemplo:
Para leer palabras clave, debemos llamar a Elementos (" palabra clave ") no Elementos (" palabras clave " ) ya que keywords es un nodo raíz.
// 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);
}
Puede obtener un valor de atributo utilizando foo.Attribute (" bar "). Valor , pero este método generará una excepción si falta el atributo. La forma segura de obtener el valor del atributo es (cadena) foo.Attribute (" barra ") : le dará nulo si falta el atributo
Otros consejos
Una vez más, me sorprende que las personas ni siquiera prueben sus respuestas y que las personas todavía voten cuando no trabajan. Los .Elementos obtendrán la lista de elementos en la raíz actual, que no es una palabra clave.
También el que usa .Atributos [" X "] ni siquiera compila lo que necesita usar (), por supuesto, nuevamente estaría operando en cada instancia de " palabras clave " no " palabra clave "
Puedes usar
var keywords = from kw in ga.ArticleKeywords.Element("keywords").Elements()
o
var keywords = from kw in ga.ArticleKeywords.Element("keywords").Elements("keyword")
o (esto obtendrá todos los elementos de palabras clave independientemente del nivel)
var keywords = from kw in ga.ArticleKeywords.Descendants("keyword")
Pensaría que algo como esto funcionaría
var keywordData = from k in ga.ArticleKeywords.Elements("Keywords")
select new { Value = k.Attributes["value"].Value,
Display = k.Attributes["display"].Value};
Esto le daría un IEnumerable de un tipo anónimo que contiene un valor y una propiedad de visualización. Dependiendo de lo que esté haciendo, podría reemplazar fácilmente el tipo anónimo por un tipo concreto.