【问题标题】:Get the value of a child node from a list of nodes, XML Xpath C#从节点列表中获取子节点的值,XML Xpath C#
【发布时间】:2019-02-05 12:27:07
【问题描述】:

我正在开发一个使用 Unity 在 3D 环境中生成节点图的应用程序。为了生成节点,我需要从 Graphml 文件中为它们分配值。

我没有太多使用 XML 的经验,所以我不确定它是如何工作的。我做了一些研究并尝试了很多东西,但我无法让它发挥作用。

这就是问题所在。我想访问每个节点/边缘元素的子元素的值。但我不知道怎么做。这是我的代码。节点和边元素位于 xmlNodeLists 中。

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using Topology;

public class GraphMLReaderThree : MonoBehaviour {

public TextAsset xmlRawFile;

void Start()
{
    string data = xmlRawFile.text;

    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(data);

    int scale = 2;

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("node");
    XmlNodeList edgeList = xmlDoc.GetElementsByTagName("edge");
    Debug.Log(nodeList.Count);
    XmlNode targetNode = 
    nodeList[0].SelectNodes("//data[@key='author.activity']")[0];
    if (targetNode != null)
    {
        string valor = targetNode.InnerText;
        Debug.Log(valor);
    }
    else
    {
        Debug.Log("No nodes found");
    }
} 

这是 Graphml 的一个节点。我不知道如何使用数据密钥访问那些孩子。

    <node id="247983">
        <data key="author.regDate">2010-10-27 23:09:40</data>
        <data key="author.location">Raleigh, NC</data>
        <data key="author.descr">The official twitter account for Red Hat 
        Training, Certification, and Consulting</data>
        <data key="author.pub.descr">Twitter</data>
        <data key="author.country">us</data>
        <data key="author.website">http://www.redhat.com/services</data>
        <data key="author.friends">813</data>
        <data key="author.activity">1</data>
        <data key="author.origId">208736299</data>
        <data key="author.personName">Red Hat Services</data>
        <data key="author.pub.id">11</data>
        <data key="author.tzone">Central Time (US &amp; Canada)</data>
        <data key="author.lon">-78.6386</data>
        <data key="author.name">RedHat_Services</data>
        <data key="author.lat">35.7721</data>
        <data key="author.audience">18155</data>
        <data key="author.eigen.centrality">1.0</data>
        <data key="author.modularity.class">247983</data>
        <data key="author.modularity.size">15</data>
        <data key="coords.x">7.624482</data>
        <data key="coords.y">-11.719869</data>
        <data key="coords.z">-0.9229746</data>
    </node>

问题是,Debug.Log 跳到“未找到节点”。但是列表中充满了节点元素,并且 xPath 查询是正确的。也许我没有使用正确的功能。我希望得到这个孩子的价值1,特别是“author.Activity”孩子。一旦成功,获取所有子节点并将它们分配给 3D 节点值。

【问题讨论】:

  • 你的代码运行良好,给我一个1。首先在简单的控制台应用程序中尝试您的代码,然后再集成到您的主项目中
  • 它在 Unity 中运行良好,我不知道为什么。但没关系,我尝试了另一种有效的方法。非常感谢!

标签: c# xml visual-studio unity3d xpath


【解决方案1】:

我使用 XML Linq 创建了一个嵌套字典:

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

namespace ConsoleApplication100
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            Dictionary<string, Dictionary<string, string>> dict = doc.Descendants("node")
                .GroupBy(x => (string)x.Attribute("id"), y => y.Elements("data")
                    .GroupBy(a => (string)a.Attribute("key"), b => (string)b)
                    .ToDictionary(a => a.Key, b => b.FirstOrDefault()))
                    .ToDictionary(x => x.Key, y => y.FirstOrDefault());

        }
    }
}

【讨论】:

  • 我喜欢这种方法。我急于使项目工作,但我在优化代码时肯定会使用它。非常感谢!
【解决方案2】:

Xpath 出于某种原因没有给我结果。它给了我一个空异常。所以我尝试了另一种方法,并且成功了。这是一个肮脏的解决方案,因为我需要再添加 20 个条件,但至少它有选择地为我提供了来自 XML 的信息。

现在这对我有用,直到我找到优化的解决方案。感谢您的帮助!

void Start () {
    string data = xmlRawFile.text;
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(data);
    XmlNodeList nodes = xmlDoc.GetElementsByTagName("node");
    Debug.Log(nodes.Count);

    foreach (XmlNode node in nodes)
    {
        string aux=node.Attributes["id"].Value;           
        XmlNodeList childs = node.ChildNodes;

        Debug.Log(childs.Count);
        Debug.Log(aux);
        for(int i=0; i<childs.Count;i++)
        {
            if(childs[i].Attributes["key"].Value == "author.name")
            {
                Debug.Log(childs[i].InnerText);
            }            
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多