简体   繁体   English

从节点列表XML Xpath C#获取子节点的值

[英]Get the value of a child node from a list of nodes, XML Xpath C#

I am working on an app that generates Node graphs in a 3D environment using Unity. 我正在开发一个使用Unity在3D环境中生成节点图的应用程序。 In order to generate the Nodes, I need to assign them values from a Graphml file. 为了生成节点,我需要从Graphml文件分配它们的值。

I dont have much experience with XML, so I'm not sure how anything works. 我在XML方面没有太多经验,所以我不确定任何工作原理。 I've done some research and tried many things but I cannot make it work. 我已经做过一些研究,尝试了很多事情,但是我无法使它起作用。

This is the problem. 这就是问题。 I want to access the value of the children of each Node/Edge elements. 我想访问每个Node / Edge元素的子代的值。 But I don't know how. 但是我不知道如何。 This is the code I have. 这是我的代码。 The nodes and edges elements are inside xmlNodeLists. 节点和边元素位于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");
    }
} 

And this is one node of the Graphml. 这是Graphml的一个节点。 I dont know how to access those Children with the data key thing. 我不知道如何使用数据键访问那些孩子。

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

The problem is, the Debug.Log skips to "No Nodes Found". 问题是, Debug.Log跳到“未找到节点”。 But the Lists are full of node elements and the xPath query is correct. 但是列表中充满了节点元素,并且xPath查询是正确的。 Maybe im not using the correct functions. 也许我没有使用正确的功能。 I expect to get the value 1 of this child in particular "author.Activity" child in particular. 我希望特别是获得该子项的值1,尤其是“ author.Activity”子项。 And once it works, get all children and assign them to the 3D Node values. 并且一旦起作用,请获取所有子代并将其分配给3D节点值。

I used XML Linq to create a nested dictionary : 我使用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());

        }
    }
}

Xpath doesn't give me the results for some reason. Xpath出于某种原因没有给我结果。 It gives me a Null exception. 它给了我一个空异常。 So I tried with another approach and I made it work. 因此,我尝试了另一种方法,并使它起作用。 It's a dirty solution, since I will need to add 20 more conditions, but at least it gives me the information from the XML selectively. 这是一个肮脏的解决方案,因为我将需要添加20个以上的条件,但是至少它有选择地为我提供了来自XML的信息。

For now this works for me until I find an optimized solution. 目前,这对我一直有效,直到找到最佳解决方案为止。 Thanks for the help! 谢谢您的帮助!

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM