导航XML节点时出现问题.只有在特定元素时才需要子节点

本文关键字:元素 子节点 节点 XML 问题 导航 | 更新日期: 2023-09-27 18:25:38

我第一次使用XML,我得到了一个地址的XML文件,其中包括States Cities、Street和House Numbers的元素这是我的XML文件的缩写版本,很抱歉它太长了。

<?xml version="1.0" encoding="UTF-8"?>
    <Locations>
       <State>
          Ohio OH
          <City>
             Cincinnati
             <Street>
                Walnut Street
                <Number>650</Number>
                <Number>600</Number>
                <Number>700</Number>
                <Number>414</Number>
             </Street>
             <Street>
                Woolper Ave
                <Number>110</Number>
             </Street>
             <Street>
                Worth Ave
                <Number>2022</Number>
             </Street>
             <Street>
                Madison Rd
                <Number>3081</Number>
             </Street>
             <Street>
                Wasson Rd
                <Number>3376</Number>
             </Street>
             <Street>
                Wooster Pike
                <Number>6906</Number>
                <Number>7453</Number>
             </Street>
             <Street>
                Woodcroft Dr
                <Number>7314</Number>
             </Street>
             <Street>
                Pike St
                <Number>316</Number>
             </Street>
             <Street>
                Wocher Ave
                <Number>119</Number>
             </Street>
             <Street>
                Fairfield Ave
                <Number>3244</Number>
             </Street>
             <Street>
                Glen Este-Withamsville Rd
                <Number>4450</Number>
             </Street>
             <Street>
                Linwood Ave
                <Number>3151</Number>
                <Number>3209</Number>
             </Street>
             <Street>
                Newtown Rd
                <Number>3811</Number>
             </Street>
             <Street>
                Round Bottom Rd
                <Number>3700</Number>
             </Street>
             <Street>
                Main St
                <Number>7849</Number>
             </Street>
             <Street>
                Eastgate Blvd
                <Number>4501</Number>
             </Street>
          </City>
          <City>
             New Richmond
             <Street>
                front
                <Number />
             </Street>
          </City>
          <City>
             Batavia
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Bethel
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Amelia
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Williamsburg
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Dayton
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Columbus
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Cleveland
             <Street>
                <Number />
             </Street>
          </City>
          <City>
             Washington Court House
             <Street>
                <Number />
             </Street>
          </City>
       </State>
       <State>
          Alabama AL
          <City>
             <Street>
                <Number />
             </Street>
          </City>
       </State>
       <State>
          Montana MT
          <City>
             <Street>
                <Number />
             </Street>
          </City>
       </State>
       <State>
          Alaska AK
          <City>
             <Street>
                <Number />
             </Street>
          </City>
       </State>
       <State>
          Nebraska NE
          <City>
             <Street>
                <Number />
             </Street>
          </City>
       </State>
       <State>
          Arizona AZ
          <City>
             <Street>
                <Number />
             </Street>
          </City>
       </State>
    </Locations>

无论如何,我试图添加俄亥俄州元素内的城市。

我尝试过使用System.Xml、System.Xml.Linq和System.Xml.XPath;

Xpath显示了最大的希望,但我很难确定是否可以返回属于特定元素的元素。例如包含"俄亥俄州OH"的州元素内的所有城市元素。我完全有可能需要将属性附加到这些元素上。

我的计划是将各州加载到列表框中,然后根据所选的州在另一个列表框中显示树下的城市,依此类推。

我现在拥有的添加状态的代码如下。这很好用,因为它只有1层深。

XmlNodeList nodeList;
        XmlNode root = doc.DocumentElement;
        nodeList = root.SelectNodes("//Locations/State");
        foreach (XmlNode state in nodeList)
        {
            Listbox1.Items.Add(state.FirstChild.InnerText);
        }

我认为我的问题在于使用FirstChild、NextSibling之类的东西。

谢谢你的帮助。希望我能很好地解释我的问题。

导航XML节点时出现问题.只有在特定元素时才需要子节点

您可以使用[]过滤元素,因此要仅获得元素文本包含"Ohio OH"的State-元素,请执行:

/Locations/State[contains(text(), 'Ohio OH')]

要获得这些元素的City-子元素,请执行以下操作:

/Locations/State[contains(text(), 'Ohio OH')]/City

contains()-函数在XPath规范中有文档说明。

试试这个。它只返回不带子项、空格和return的name部分。我更新了代码,意识到如果纽约州包含俄亥俄街,该州将匹配。

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)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var result = doc.Descendants("State").Where(x => x.Nodes().FirstOrDefault().ToString().Trim().Contains("Ohio")).Elements("City").Select(y => new {
                City = y.Nodes().FirstOrDefault().ToString().Trim(),
                Streets = y.Elements("Street").Select(z => new {
                    StreeName = z.Nodes().FirstOrDefault().ToString().Trim(),
                    Numbers = z.Elements("Number").Select(a => new {
                        Number = a.Value
                    }).ToList()
                }).ToList()
            }).ToList();
        }
    }
}