Leer un XML (de una cadena) y obtener algunos campos - Problemas al leer XML

82

Tengo este XML (almacenado en una cadena C # llamada myXML)

<?xml version="1.0" encoding="utf-16"?>
<myDataz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <listS>
    <sog>
      <field1>123</field1>
      <field2>a</field2>
      <field3>b</field3>
    </sog>
    <sog>
      <field1>456</field1>
      <field2>c</field2>
      <field3>d</field3>
    </sog>
  </listS>
</myDataz>

y me gustaría explorar todos los <sog>elementos. Para cada uno de ellos, me gustaría imprimir el niño <field1>.

Entonces este es mi código:

XmlDocument xmlDoc = new XmlDocument();
string myXML = "<?xml version=\"1.0\" encoding=\"utf-16\"?><myDataz xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><listS><sog><field1>123</field1><field2>a</field2><field3>b</field3></sog><sog><field1>456</field1><field2>c</field2><field3>d</field3></sog></listS></myDataz>"
xmlDoc.Load(myXML);
XmlNodeList parentNode = xmlDoc.GetElementsByTagName("listS");
foreach (XmlNode childrenNode in parentNode)
{
    HttpContext.Current.Response.Write(childrenNode.SelectSingleNode("//field1").Value);
}

pero parece que no puedo leer una cadena como XML? yo obtengoSystem.ArgumentException

Markzzz
fuente
2
¿Qué dice la excepción ?
SLaks
¿Puedes usar XDocument en .NET 4.0?
JohnD
¡Estoy en .NET 3.5! ¡Escribí la excepción!
Markzzz
1
¿Cuál es el mensaje de excepción ?
SLaks
XLINQ es totalmente compatible con .Net 3.5 y es mucho más fácil de usar.
SLaks

Respuestas:

107

Debe usar el método LoadXml, no Load:

xmlDoc.LoadXml(myXML); 

El método de carga está intentando cargar xml desde un archivo y LoadXml desde una cadena. También puede usar XPath:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);

string xpath = "myDataz/listS/sog";
var nodes = xmlDoc.SelectNodes(xpath);

foreach (XmlNode childrenNode in nodes)
{
    HttpContext.Current.Response.Write(childrenNode.SelectSingleNode("//field1").Value);
} 
Andrey Marchuk
fuente
Increíble fácil. Finalmente puedo empezar a trabajar con API :).
C4d
7
En lugar de SelectSingleNode("//field1").Valuedebería ser SelectSingleNode("//field1").InnerTexto SelectSingleNode("//field1").InnerXml, porque Value sería nulo, ya que no es un atributo, pero el valor está entre las etiquetas.
Mathias Conradt
3
Para agregar a @MathiasConradt, debería serlo SelectSingleNode("field1").InnerTextsi no desea leer siempre el field1de la primera aparición de myDataz / listS / sog.
Matthieu M.
19

Utilice Linq-XML,

XDocument doc = XDocument.Load(file);

var result = from ele in doc.Descendants("sog")
              select new
              {
                 field1 = (string)ele.Element("field1")
              };
 foreach (var t in result)
  {
      HttpContext.Current.Response.Write(t.field1);
  }

O BIEN: Obtenga la lista de nodos de <sog>etiquetas.

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.Load(myXML);
 XmlNodeList parentNode = xmlDoc.GetElementsByTagName("sog");
 foreach (XmlNode childrenNode in parentNode)
  {
    HttpContext.Current.Response.Write(childrenNode.SelectSingleNode("field1").InnerText);
   }
adatapost
fuente
11

Las otras respuestas tienen varios años (y no funcionan para Windows Phone 8.1), así que pensé en usar otra opción. Usé esto para analizar una respuesta RSS para una aplicación de Windows Phone:

XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(xml_string);
sraboy
fuente
3

O use la clase XmlSerializer.

XmlSerializer xs = new XmlSerializer(objectType);
obj = xs.Deserialize(new StringReader(yourXmlString));
teebot
fuente
2

Usé System.Xml.Linq.XElement para este propósito. Simplemente verifique el código a continuación para leer el valor del primer nodo hijo del xml (no el nodo raíz).

        string textXml = "<xmlroot><firstchild>value of first child</firstchild>........</xmlroot>";
        XElement xmlroot = XElement.Parse(textXml);
        string firstNodeContent = ((System.Xml.Linq.XElement)(xmlroot.FirstNode)).Value;
MONSEÑOR
fuente