Przeczytaj XML (z łańcucha) i pobierz kilka pól - Problemy z odczytem XML

83

Mam ten XML (przechowywany w ciągu C # o nazwie 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>

i chciałbym przejrzeć wszystkie <sog>elementy. Dla każdego z nich chciałbym wydrukować dziecko <field1>.

Więc to jest mój kod:

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);
}

ale wygląda na to, że nie mogę odczytać ciągu jako XML? dostajęSystem.ArgumentException

markzzz
źródło
2
Co mówi wyjątek ?
SLaks
Czy możesz używać XDocument w .NET 4.0?
JohnD
Jestem na .NET 3.5! Napisałem wyjątek!
markzzz
1
Jaki jest komunikat o wyjątku ?
SLaks
XLINQ jest w pełni obsługiwany na .Net 3.5 i jest znacznie łatwiejszy w użyciu.
SLaks

Odpowiedzi:

109

Powinieneś użyć metody LoadXml, a nie Load:

xmlDoc.LoadXml(myXML); 

Load metoda próbuje załadować xml z pliku i LoadXml z ciągu znaków. Możesz także użyć 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
źródło
Niesamowicie łatwe. Wreszcie mogę rozpocząć pracę z API :).
C4d
7
Zamiast SelectSingleNode("//field1").Valuetego powinno być SelectSingleNode("//field1").InnerTextlub SelectSingleNode("//field1").InnerXml, ponieważ wartość byłaby zerowa, ponieważ nie jest to atrybut, ale wartość znajduje się między tagami.
Mathias Conradt,
3
Aby dodać do @MathiasConradt, powinno tak być, SelectSingleNode("field1").InnerTextjeśli nie chcesz zawsze czytać field1pierwszego wystąpienia myDataz / listS / sog.
Matthieu M.,
19

Użyj 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);
  }

LUB: Pobierz listę węzłów <sog>tagu.

 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
źródło
11

Pozostałe odpowiedzi mają kilka lat (i nie działają na Windows Phone 8.1), więc pomyślałem, że spróbuję wybrać inną opcję. Użyłem tego do przeanalizowania odpowiedzi RSS dla aplikacji Windows Phone:

XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(xml_string);
soja
źródło
3

Lub użyj klasy XmlSerializer.

XmlSerializer xs = new XmlSerializer(objectType);
obj = xs.Deserialize(new StringReader(yourXmlString));
czajniczek
źródło
2

W tym celu użyłem System.Xml.Linq.XElement. Po prostu sprawdź poniższy kod, aby odczytać wartość pierwszego węzła podrzędnego XML (nie węzła głównego).

        string textXml = "<xmlroot><firstchild>value of first child</firstchild>........</xmlroot>";
        XElement xmlroot = XElement.Parse(textXml);
        string firstNodeContent = ((System.Xml.Linq.XElement)(xmlroot.FirstNode)).Value;
MGR
źródło