如何获取XML树中节点的线性顺序?

时间:2016-02-10 09:18:14

标签: c# xml

假设我们有以下XML

<S>
  <NP>
    <N>
      <W>John</W>
    </N>
    <MN>
      <W>Smith</W>
    </MN>
  </NP>
  <VP>
    <V>
      <W>Asked</W>
    </V>
    <NP>
      <N>
        <W>Me</W>
      </N>
    </NP>
  </VP>
</S>

如何获取树中W节点的线性顺序?例如,对于Me,它是4。

我试过

private bool GetOrder(XmlNode xmlNode, XmlNode node)
{
    if (xmlNode == node)
    {
        return true;
    }
    else
    {              
        foreach (XmlNode item in xmlNode.ChildNodes)
        {

            if (GetOrder(item, node))
            {
                return;
            }
            if (item.Name == "w")
            {
                word_order++;
            }
        }
    }
    return false;
}

我在C#中使用System.XML函数寻找最简单的方法。

3 个答案:

答案 0 :(得分:1)

您可以使用GetElementsByTagName和FindOrder方法。

        private int FindOrder(XmlDocument doc, XmlNode node, string tagName)
        {
            var arr = doc.GetElementsByTagName(tagName);
            for (var i = 0; i < arr.Count; i++)
            {
                if (arr.Item(i) == node) return i + 1;
            }
            return -1;
        }

        [TestMethod]
        public void TestMethod1()
        {

            var doc = new XmlDocument();
            doc.LoadXml(@"
 <S>
   <NP>
      <N>
      <W> John </W>
      </N>
    <MN>
       <W> Smith </W>
    </MN>
  </NP>
  <VP>
     <V>
       <W>Asked</W>
     </V>
     <NP>
        <N><W>Me</W>
        </N>
      </NP>
    </VP>
  </S>");

            var el = doc.SelectNodes("//VP/NP/N/W").Item(0);
            Assert.AreEqual(FindOrder(doc, el, "W"), 4);
        }

答案 1 :(得分:0)

我想你想学习节点的深度。您可以使用XmlTextReader类。您可以在MSDN

上找到相关文档

XmlTextReader.Depth属性获取XML文档中当前节点的深度。您可以使用XmlTextReader读取XML文档,并获取具有depth属性的节点的深度。

以下是MSDN的代码段:

using System;
using System.IO;
using System.Xml;

public class Sample{

  public static void Main(){

    // Create the XML fragment to be parsed.
    string xmlFrag  = 
    @"<book> 
         <misc>
           <style>paperback</style> 
           <pages>240</pages>
         </misc> 
        </book>";

    // Create the XmlNamespaceManager.
    NameTable nt = new NameTable();
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);

    // Create the XmlParserContext.
    XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);

    // Create the reader.
    XmlTextReader reader = new XmlTextReader(xmlFrag, XmlNodeType.Element, context);

    // Parse the XML and display each node.
    while (reader.Read()){
       switch (reader.NodeType){
         case XmlNodeType.Element:
           Console.Write("{0} {1},{2}  ", reader.Depth, reader.LineNumber, reader.LinePosition);
           Console.WriteLine("<{0}>", reader.Name);
           break;
         case XmlNodeType.Text:
           Console.Write("{0} {1},{2}  ", reader.Depth, reader.LineNumber, reader.LinePosition);
           Console.WriteLine("  {0}", reader.Value);
           break;
         case XmlNodeType.EndElement:
           Console.Write("{0} {1},{2}  ", reader.Depth, reader.LineNumber, reader.LinePosition);
           Console.WriteLine("</{0}>", reader.Name);
           break;
       }       
    }           

    // Close the reader.
    reader.Close();      
  }
}

答案 2 :(得分:0)

更简单的解决方案可能是使用SelectNodes(".//w")

    private int NodeOrder(XmlNode node)
    {
        word_order = 1;
        XmlNodeList list = xml.SelectNodes(".//w");
        foreach (XmlNode item in list)
        {
            if (item == node)
                break;
            word_order++;

        }
        return word_order;
    }