#c# #xml #linq #generics
#c# #xml #linq #общие сведения
Вопрос:
Я хочу прочитать иерархию XML в дереве объектов в памяти. Дерево XML может иметь n дочерних уровней. Я не знаю точного числа. Мои объекты в памяти имеют дочерние и родительские свойства, которые должны быть привязаны к элементу управления деревом.
Как я могу прочитать xml-файл / строку общим способом в мои объекты в памяти, когда я не знаю, как именно вызываются / записываются теги xml-элементов?
Например, кто-то может предоставить мне XML-структуру единиц, где каждая единица имеет много единиц и т.д… итак, я знаю, что xml-тег — это «unit», но это может быть и «module» или что-то еще … он должен работать в общем виде, но я не знаю, что спросить у пользователя, вводящего имя тега xml-элемента, например «unit».
Возможно ли это вообще, чего я хочу достичь?
Комментарии:
1. Вы, кажется, описываете концепцию DOM. Ваши общие объекты в памяти с дочерними и родительскими свойствами звучат точно так же, как узлы DOM.
2. Мои объекты в памяти — это ViewModels, являющиеся источником данных для элемента управления treeview
Ответ №1:
В любом случае, вы должны знать имя узла для анализа иерархии, по крайней мере, у вас должно быть определение. ИМХО, XElement
это единственный универсальный XML
синтаксический анализатор. Например, у вас есть XML, подобный этому:
<module name="core">
<modules>
<module name="xml">
<modules>
<module name="reader" />
<module name="writer" />
</modules>
</module>
<module name="json">
<modules>
<module name="serializer" />
<module name="deserializer" />
</modules>
</module>
</modules>
</module>
Как я уже говорил ранее, у вас должны быть некоторые определения, такие как root node
обязательное имя иерархического элемента и дочерний контейнер root node name s
. Это один из простых способов, с помощью которого вы можете позволить своим пользователям указывать любые имена узлов, которые они пожелают, но с некоторыми ограничениями.
Вы можете проанализировать XML
использование XElement
следующим образом:
XElement xElement = XElement.Load(@"pathtoyourxmlfile");
string rootNodeName = xElement.Name.LocalName;
IEnumerable<XElement> xElements = xElement.Descendants(rootNodeName "s");
И, конечно, вы можете Linq
xElements
использовать и для анализа иерархии, которую вы можете повторить, чтобы построить свой элемент управления деревом.
Вы можете начать работу с XElement по этим ссылкам ниже:
- http://www.dotnetperls.com/xelement
- Java2s
- http://www.joe-stevens.com/2010/01/08/linq-to-xml-tutorial/
Надеюсь, это помогло.
Комментарии:
1. Я знаю. Потомки и, похоже, ваш код будет работать 😉 Я последую вашему предложению: rootNodeName «s»); это нормально для меня, я думаю, СЕЙЧАС!
Ответ №2:
Я бы просто загрузил его, XmlDocument
а затем построил проходящее дерево XmlNodes
.
Комментарии:
1. @Jakuk если я не знаю XML-файл клиента и его структуру, было бы безумием просто читать каждый узел и предполагать, что я все делаю правильно… прежде всего, откуда я мог бы узнать имя тегов xml-элемента?
2. @msfanboy — либо вы знаете имена узлов и хотите читать только их, либо вы их не знаете и хотите прочитать весь файл. Другого способа нет. Вы спросили
how to read xml file in a generic way when nodes are not known
. Если вы хотите получить другой ответ, задайте другой вопрос
Ответ №3:
Я считаю, что можно достичь того, чего вы хотите достичь. Я бы сделал это примерно так:
class GenericNode
{
private List<GenericNode> _Nodes = new List<GenericNode>();
private List<GenericKeyValue> _Attributes = new List<GenericKeyValue>();
public GenericNode(XElement Element)
{
this.Name = Element.Name;
this._Nodes.AddRange(Element.Elements()
.Select(e => New GenericNode(e));
this._Attributes.AddRange(
Element.Attributes()
.Select(a => New GenericKeyValue(a.Key, a.Value))
}
public string Name { get; private set; }
public IEnumerable<GenericNode> Nodes
{
get
{
return this._Nodes;
}
}
public IEnumerable<GenericKeyValue> Attributes
{
get
{
return this._Attributes;
}
}
}
class GenericKeyValue
{
public GenericKeyValue(string Key, string Value)
{
this.Key = Key;
this.Value = Value;
}
public string Key { get; set; }
public string Value { get; set; }
}
Затем вы просто:
XElement rootElement = XElement.Parse(StringOfXml); // or
XElement rootElement = XElement.Load(FileOfXml);
GenericNode rootNode = new GenericRode(rootElement);
Ответ №4:
Взгляните на XmlTextReader и на пакет System.Xml
. Эти статьи также помогут вам:
Ответ №5:
Нравится это?
using System.Xml ;
using System.IO;
class Program
{
static void Main( string[] args )
{
using ( Stream inputStream = OpenXmlStream() )
{
XmlDocument document = new XmlDocument() ;
document.Load( inputStream ) ;
Process( document ) ;
}
}
static Stream OpenXmlStream()
{
// provide an input stream for the program
}
static void Process( XmlDocument document )
{
// do something useful here
}
}