XMLReader - Как прочитать этот шаблон элемента / узла - PullRequest
0 голосов
/ 26 августа 2018

Это какой-то XML, который мне нужно читать.Мне нужно получить значения QualitySetting для каждой функции, назначенной некоторым переменным:

   <?xml version="1.0" encoding="UTF-8" ?>
   <GraphicsConfig>
      <FX>
       <Off>
           <LocalisationName>$QUALITY_OFF;</LocalisationName>
        <Item>
            <Feature>LightCones</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
        <Item>
            <Feature>LensFlares</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
        <Item>
            <Feature>Debris</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
        <Item>
            <Feature>ParticleEffects</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
        <Item>
            <Feature>Trails</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
        <Item>
            <Feature>Beams</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
        <Item>
            <Feature>Fog</Feature>
            <QualitySetting>0</QualitySetting>
        </Item>
    </Off>
   </FX>
 </GraphicsConfig>

Я использую XMLReader и обычно использую что-то вроде:

Dim guiSettings = XElement.Load(_localAppDataFilePath & "\Frontier Developments\Elite Dangerous\Options\Graphics\GraphicsConfigurationOverride.xml")
            target = guiSettings.Element("GUIColour").Elements("Default").[Single]()
            r = target.Element("MatrixRed").Value

Открыть для этого другими способамии если нет простого способа сделать это, я очень рад просто найти элемент <Feature> с соответствующим именем, а затем просто просто прочитать следующий узел, но решил спросить, так как всегда хочу улучшитьмои знания по редактированию XML.

1 Ответ

0 голосов
/ 26 августа 2018

В приведенном ниже коде используется комбинация XmlReader и XML Linq.Я опубликовал это решение много раз.В этом случае я предпочитаю не использовать XmlReader вместо XML Linq, чтобы поместить результаты в словарь и опубликовать этот код.Для больших файлов XML всегда лучше использовать XmlReader, чтобы избежать ошибки нехватки памяти.

Я разместил решение как на c #, так и на vb.net


Imports System.Xml
Imports System.Xml.Linq
Module Module1

    Const FILENAME As String = "c:\temp\test.xml"
    Sub Main()
        Dim reader As XmlReader = XmlReader.Create(FILENAME)
        Dim items As List(Of Item) = New List(Of Item)()
        While (Not reader.EOF)

            If reader.Name <> "item" Then
                reader.ReadToFollowing("Item")
            End If

            If Not reader.EOF Then

                Dim xItem As XElement = XElement.ReadFrom(reader)
                Dim item As Item = New Item()
                item.feature = xItem.Element("Feature")
                item.setting = xItem.Element("QualitySetting")

                items.Add(item)
            End If
        End While

        'using a dictionary 
        Dim doc As XDocument = XDocument.Load(FILENAME)
        Dim dict As Dictionary(Of String, String) = doc.Descendants("Item") _
            .GroupBy(Function(x) x.Element("Feature").ToString(), Function(y) y.Element("QualitySetting").ToString()) _
            .ToDictionary(Function(x) x.Key, Function(y) y.FirstOrDefault())

    End Sub

End Module
Public Class Item

    Public feature As String
    Public setting As String
End Class

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            List<Item> items = new List<Item>();
            while (!reader.EOF)
            {
                if(reader.Name != "item")
                {
                    reader.ReadToFollowing("Item");
                }
                if (!reader.EOF)
                {
                    XElement xItem = (XElement)XElement.ReadFrom(reader);
                    Item item = new Item() {
                        feature = (string)xItem.Element("Feature"),
                        setting = (string)xItem.Element("QualitySetting")
                    };

                    items.Add(item);
                }
            }

            //using a dictionary 
            XDocument doc = XDocument.Load(FILENAME);
            Dictionary<string, string> dict = doc.Descendants("Item")
                .GroupBy(x => (string)x.Element("Feature"), y => (string)y.Element("QualitySetting"))
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
        }
    }
    public class Item
    {
        public string feature { get; set; }
        public string setting { get; set; }
    }
}
...