Подтвердить что ты не робот

С# как я могу получить все имена элементов из XML файла

Я хотел бы получить все имя элемента из xml файла, например, xml файл,

<BookStore>
  <BookStoreInfo>
    <Address />
    <Tel />
    <Fax />
  <BookStoreInfo>
  <Book>
    <BookName />
    <ISBN />
    <PublishDate />
  </Book>
  <Book>
   ....
  </Book>
</BookStore>

Я хотел бы получить имя элемента "BookName". "ISBN" и "PublishDate" и только те имена, которые не включают "BookStoreInfo" и дочернее имя node

Я пробовал несколько способов, но не работает, как я могу это сделать?

4b9b3361

Ответ 1

Ну, с XDocument и LINQ-to-XML:

foreach(var name in doc.Root.DescendantNodes().OfType<XElement>()
        .Select(x => x.Name).Distinct())
{
    Console.WriteLine(name);
}

Однако есть много похожих маршрутов.

Ответ 2

Использование XPath

XmlDocument xdoc = new XmlDocument(); 
xdoc.Load(something);
XmlNodeList list = xdoc.SelectNodes("//BookStore");

предоставляет список со всеми узлами в документе с именем BookStore

Ответ 3

Я согласен с Адамом, идеальным условием является наличие схемы, определяющей содержание XML-документа. Однако иногда это невозможно. Вот простой способ для итерации всех узлов XML-документа и использования словаря для хранения уникальных локальных имен. Мне нравится отслеживать глубину каждого локального имени, поэтому я использую список int для хранения глубины. Обратите внимание, что XmlReader "прост в памяти", поскольку он не загружает весь документ, как это делает XmlDocument. В некоторых случаях это мало чем отличается от размера данных xml. В следующем примере файл 18.5MB читается с помощью XmlReader. Использование XmlDocument для загрузки этих данных было бы менее эффективным, чем использование XmlReader для чтения и выборки его содержимого.

string documentPath = @"C:\Docs\cim_schema_2.18.1-Final-XMLAll\all_classes.xml";

Dictionary<string, List<int>> nodeTable = new Dictionary<string, List<int>>();
using (XmlReader reader = XmlReader.Create(documentPath))
{
    while (!reader.EOF)
    {
        if (reader.NodeType == XmlNodeType.Element)
        {
            if (!nodeTable.ContainsKey(reader.LocalName))
            {
                nodeTable.Add(reader.LocalName, new List<int>(new int[] { reader.Depth }));
            }
            else if (!nodeTable[reader.LocalName].Contains(reader.Depth))
            {
                nodeTable[reader.LocalName].Add(reader.Depth);
            }
        }
        reader.Read();
    }
}
Console.WriteLine("The node table has {0} items.",nodeTable.Count);
foreach (KeyValuePair<string, List<int>> kv in nodeTable)
{
    Console.WriteLine("{0} [{1}]",kv.Key, kv.Value.Count);
    for (int i = 0; i < kv.Value.Count; i++)
    {
        if (i < kv.Value.Count-1)
        {
            Console.Write("{0}, ", kv.Value[i]);
        }
        else
        {
            Console.WriteLine(kv.Value[i]);
        }
    }
}

Ответ 4

Пуристы делают это (и, если быть справедливым, правильный путь), должны иметь определение контракта схемы и читать его таким образом. При этом вы можете сделать что-то вроде этого...

List<string> nodeNames = new List<string>();

foreach(System.Xml.XmlNode node in doc.SelectNodes("BookStore/Book"))
{
    foreach(System.Xml.XmlNode child in node.Children) 
    {
        if(!nodeNames.Contains(child.Name)) nodeNames.Add(child.Name);
    }
}

Это, по общему признанию, рудиментарный метод для получения списка различных имен node для детей Book node, но вы не указали многое другое на пути вашей среды (если у вас есть 3.5, вы можете использовать LINQ to XML, чтобы сделать это немного красивее, например), но это должно сделать работу независимо от вашей среды.

Ответ 5

Если вы используете С# 3.0, вы можете сделать следующее:

var data = XElement.Load("c:/test.xml"); // change this to reflect location of your xml file

var allElementNames = 
    (from e in in data.Descendants()
    select e.Name).Distinct();

Ответ 6

Вы можете попробовать сделать это с помощью XPATH.

XmlDocument doc = new XmlDocument();
doc.LoadXml("xml string");

XmlNodeList list = doc.SelectNodes("//BookStore/Book");

Ответ 7

Если BookStore является корневым элементом ur, тогда вы можете попробовать следующий код

XmlDocument doc = new XmlDocument();
        doc.Load(configPath);
        XmlNodeList list = doc.DocumentElement.GetElementsByTagName("Book");
        if (list.Count != 0)
        {
            for (int i = 0; i < list[0].ChildNodes.Count; i++)
            {
                XmlNode child = list[0].ChildNodes[i];

            }
        }

Ответ 8

Это идеально, чтобы сохранить его в массиве или в словаре, учитывая, что у вас есть много элементов книги, и вы собираетесь получить доступ ко всему этому. Как вы можете заменить определенные атрибуты и сохранить их? Пример VA {значение для ve здесь изменено}

Ответ 9

Он-лайн инструмент, который я нахожу здесь, может красиво извлекать эти имена элементов - просто загружать XML файл и печатать имена в качестве веб-страницы результатов.

http://taporware.ualberta.ca/~taporware/xmlTools/listxml.shtml

введите описание изображения здесь