Чтение внутреннего текста одного элемента из большого XML-файла

У меня есть большой файл .xml с одним узлом, который я сохранил в виде строки. Я хочу проанализировать файл .xml для чтения определенного элемента и вывести внутренний текст. Например: я хочу прочитать элемент FrameNo и вывести BINGO в окно сообщений. Нужный элемент появится в XML-документе только один раз. Я предпочитаю использовать XmlDocument.

Я пробовал множество примеров С# .xml, но не смог получить результат.

xml текст

    <Aircraft z:Id="i1" xmlns="http://xxx.yyyyycontract.gov/2018/03/Boeing.xxxxxxxxxxxxxx.Airframe" 
    xmlns:i="http://www.xxxxxxx.com/2019/XMLSchema-instance" 
    xmlns:z="http://xxxxxxx.xxxxxxxxx.com/2005/01/Serialization/"><Timestamp i:nil="true"/> 
    <Uuid>00000000-0000-0000-0000-000000000000</Uuid><Comments i:nil="true"/><Facility>..........

и так до конца .xml

    <FrameNo>BINGO</FrameNo><WDate i:nil="true"/></Aircraft>

это раздел кода, в котором я хочу, чтобы код выполнялся.

    private void buttonLoad_Click(object sender, EventArgs e)
    {
    }

person Lynn    schedule 17.04.2020    source источник
comment
XmlDocument doc = new XmlDocument(); затем используйте doc.Load(filePath); для загрузки XML-файла и string text = doc.DocumentElement.SelectSingleNode("FrameNo").InnerText   -  person Oguz Ozgul    schedule 18.04.2020


Ответы (4)


Я думаю, это само собой разумеющееся

using System.Xml.Linq;

XElement root = XElement.Load(textXML);
XElement myElement = root.Element("FrameNo");
if (myElement != null)
    myData = myElement.InnerText;
person T.S.    schedule 17.04.2020

Благодаря jdweng я хотел поделиться окончательным кодом с другими. Это будет работать в методе, как показано ниже

    private void buttonMaint_Click(object sender, EventArgs e)
    {
    XDocument doc = XDocument.Parse(xmlinputstr); // input string from memory or input file
    XNamespace ns = doc.Root.GetDefaultNamespace();
                string[] Frame = doc.Descendants(ns + "FrameNo").Select(x => (string)x).ToArray(); // selects element to read + trailing character of >
    string frame = string.Join("", Frame); //converts from array to string
    if (string.IsNullOrEmpty(frame)) // check for empty result
    {
    txtFrame.Text = "not found"; //outputs to textbox
    }
    else
    {
    txtFrame.Text = (frame); //outputs to textbox
    }
    }

Комментарии для ясности

person Lynn    schedule 19.04.2020

Вам нужно использовать пространство имен по умолчанию. См. мое решение xml linq ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            XDocument doc = XDocument.Parse(xml);
            XNamespace ns = doc.Root.GetDefaultNamespace();

            XElement frameNo = doc.Descendants(ns + "FrameNo").FirstOrDefault();

            string frame = (string)frameNo;
            string[] serialNumbers = doc.Descendants(ns + "SerialNumber").Select(x => (string)x).ToArray(); 

        }
    }
}
person jdweng    schedule 18.04.2020
comment
это работает на 100%. Я столкнулся с неожиданной проблемой, когда некоторые элементы настроены следующим образом ‹SerialNumber i:nil=true/›, и мне нужно значение, которое находится в этом элементе ‹SerialNumber›197-15472-145-1990413‹/SerialNumber› Я пробовал все, что мог придумать, чтобы отредактировать или изменить значение в xxxxxx, чтобы включить или исключить либо пробел, либо завершающий ›, но безуспешно. Я знаю, что это пробел в первом примере, который вызывает проблему. Есть ли способ отфильтровать или проверить наличие завершающих символов в xxxxxxx или после него, чтобы я получал только внутренний текст ‹SerialNumber› - person Lynn; 19.04.2020
comment
string[] serialNumbers = doc.Descendants(ns + SerialNumber).Select(x =› (string)x).ToArray(); - person jdweng; 19.04.2020
comment
Опять же, это сработало отлично. Теперь у меня есть программа, работающая так, как я хотел. Я добавил вам особую благодарность в комментариях к коду. // особая благодарность jdweng с stackoverflow.com за необходимую помощь в написании кода - person Lynn; 19.04.2020

Обнаружилась еще одна странная загвоздка. Некоторые элементы называются так.

    <a:SupplierServDoc>

внутреннее текстовое содержимое этого элемента представляет собой пакет base64. Нет проблем с обработкой пакета base64.

Код из приведенных выше ответов правильно выводит base64, но не может обрабатывать: в имени элемента. Он выдает ошибку шестнадцатеричного символа 3A.

У меня есть этот код, который выводит внутренний текст, но не как пакет base64. Я также изучил префикс для обработки : , но с худшими результатами. По завершении я вывожу внутренний текст base 64 в виде файла .txt.

    XNamespace ad = http://www.mmmmmmmmmm.com";
    XName k = ad + "SupplierServDoc";
    string[] WING = doc.Descendants(k).Select(x => (string)x).ToArray();
    string wing = string.Join("", WING);
    if (string.IsNullOrEmpty(syncd))
    {
    MessageBox.Show("a:SupplierServDoc Base 64 code not found");
    }
    else
    {           
    MessageBox.Show("Test " + wing);
    }
person Lynn    schedule 21.04.2020