在不知道结构的情况下以通用方式读取 xml 文件/字符串

发布于 12-11 13:18 字数 288 浏览 1 评论 0原文

我想将 XML 层次结构读入内存对象树中。 XML 树可以有 n 层子级。我不知道确切的数字。我的内存中对象具有要绑定到树控件的子属性和父属性。

当我不知道 xml 元素标签是如何准确调用/写入时,如何以通用方式将 xml 文件/字符串读取到内存中对象中?

例如,有人可以为我提供一个单元的 xml 结构,其中每个单元有许多单元等...所以我知道 xml 标签是“单元”,但它也可以是“模块”或其他任何东西...它必须通用,但我不要求用户输入 xml 元素标签名称(例如“unit”)。

我想要实现的目标有可能吗?

I want to read a XML hierarchy into a tree of in-memory objects. The XML tree could have n-levels of children. I do not know the exact number. My in-memory objects have a children and parent property to be bound to a tree control.

How can I read xml file/string in a generic way into my in-memory objects when I do not know how the xml element tags are called/written exactly?

For example someone could provide me a xml structure of units where each unit has many units etc... so I know the xml tag is "unit" but it could be "module" too or anything else... it must work generic but I do not what to ask the user entering the xml element tag name like "unit".

Is that possible at all what I want to achieve?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

堇色安年2024-12-18 13:18:47

无论哪种方式,您都必须知道节点名称才能解析层次结构,至少您必须有一个定义。恕我直言,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>

正如我之前所说,您应该有一些定义,例如根节点必须是分层元素名称,子容器必须是根节点名称 + s 。这是一种简单的方法,您可以允许用户指定他们想要的任何节点名称,但有一些限制。

您可以使用 XElement 来解析 XML,如下所示:

XElement xElement = XElement.Load(@"path\to\your\xml\file");
string rootNodeName = xElement.Name.LocalName;
IEnumerable<XElement> xElements = xElement.Descendants(rootNodeName + "s");

当然,您可以 Linq xElements 并解析您可以重复构建树控件的层次结构。

您可以通过以下链接开始使用 xElement:

希望这有帮助。

Either way, you have to know the node name to parse the hierarchy at least you have to have a definition. IMHO, XElement is the only sort of generic XML parser around. For instance, you have a XML like this:

<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>

As I said earlier, you should have some definitions like the root node must the hierarchical element name and the children container must be root node name + s. This is one simple way that you can allow your users to specify any node names they wish but with some constraints.

You may parse the XML using XElement like this:

XElement xElement = XElement.Load(@"path\to\your\xml\file");
string rootNodeName = xElement.Name.LocalName;
IEnumerable<XElement> xElements = xElement.Descendants(rootNodeName + "s");

And of course you can Linq the xElements and to parse the hierarchy you can recur to build your tree control.

You may take a kick start on xElement with these links below:

Hope this helped.

怼怹恏2024-12-18 13:18:47

我只需将其加载到 XmlDocument 中,然后通过 XmlNodes 构建树。

I would just load it into XmlDocument and then build the tree going through XmlNodes.

梦归所梦2024-12-18 13:18:47

我相信你想要达到的目标是有可能实现的。我会这样做:

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

I believe it is possible to achieve what you want to achieve. I'd do it something like this:

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

Then you simply:

XElement rootElement = XElement.Parse(StringOfXml); // or
XElement rootElement = XElement.Load(FileOfXml);

GenericNode rootNode = new GenericRode(rootElement);
流云如水2024-12-18 13:18:47

像这样?

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

Like this?

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
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文