C# 从父节点到最后一个子节点获取XML标记属性值

C# 从父节点到最后一个子节点获取XML标记属性值,c#,xml,linq,C#,Xml,Linq,这是我的输入XML <?xml version="1.0" encoding="UTF-8"?> <Menu TextField="Menu"> <Menu TextField="Approvals"> <Menu TextField="Vacation/Leave"> <Menu TextField="Vacation Pre-Request Approval" /> <Me

这是我的输入XML

<?xml version="1.0" encoding="UTF-8"?>
<Menu TextField="Menu">
   <Menu TextField="Approvals">
      <Menu TextField="Vacation/Leave">
         <Menu TextField="Vacation Pre-Request Approval" />
         <Menu TextField="Vacation Approval" />
      </Menu>
      <Menu TextField="Late Come Approval" />
      <Menu TextField="Loan Approval" />
      <Menu TextField="Department Change Approval" />
      <Menu TextField="Resignation/Termination">
         <Menu TextField="Resignation Approval" />
         <Menu TextField="Resignation Clearance" />
      </Menu>
   </Menu>
   <Menu TextField="Employee Transactions">
      <Menu TextField="Change Designation" />
      <Menu TextField="Organization">
         <Menu TextField="Organization Designation & Grade" />
      </Menu>
      <Menu TextField="Change Grade" />
   </Menu>
</Menu>
我想打印TextField的第一个标记值,直到字符串中TextField的最后一个标记值。下面是我尝试过的代码,但它打印的所有文本字段值不是我需要的结构格式

var menus = (from menu in XDocument.Parse(xml).Descendants("Menu")
            select new
                {
                    TextField = (string)menu.Attribute("TextField")
                }).ToList();

试试这个LINQXML查询。确保将“&”替换为“&;”

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



namespace ConsoleApplication29
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement menu = doc.Descendants().Where(x => (string)x.Attribute("TextField") == "Menu").FirstOrDefault();
            foreach (XElement element in menu.Elements())
            {
                string textField = (string)element.Attribute("TextField");
                foreach (XElement subElement in element.Elements())
                {
                    List<string> textStrings = subElement.DescendantNodesAndSelf().Select(x => (string)((XElement)x).Attribute("TextField")).ToList();
                    textStrings.Insert(0, textField);
                    Console.WriteLine(string.Join(" > ", textStrings));
                }
            }
            Console.ReadLine();
        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序29
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
XElement menu=doc.subjects()。其中(x=>(字符串)x.Attribute(“TextField”)==“menu”).FirstOrDefault();
foreach(menu.Elements()中的XElement元素)
{
string textField=(string)element.Attribute(“textField”);
foreach(element.Elements()中的XElement子元素)
{
List textStrings=subElement.genderantnodesandself().Select(x=>(string)((XElement)x).Attribute(“TextField”).ToList();
textStrings.Insert(0,textField);
Console.WriteLine(string.Join(“>”,textStrings));
}
}
Console.ReadLine();
}
}
}

尝试此linq xml查询。确保将“&”替换为“&;”

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



namespace ConsoleApplication29
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            XElement menu = doc.Descendants().Where(x => (string)x.Attribute("TextField") == "Menu").FirstOrDefault();
            foreach (XElement element in menu.Elements())
            {
                string textField = (string)element.Attribute("TextField");
                foreach (XElement subElement in element.Elements())
                {
                    List<string> textStrings = subElement.DescendantNodesAndSelf().Select(x => (string)((XElement)x).Attribute("TextField")).ToList();
                    textStrings.Insert(0, textField);
                    Console.WriteLine(string.Join(" > ", textStrings));
                }
            }
            Console.ReadLine();
        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序29
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
XDocument doc=XDocument.Load(文件名);
XElement menu=doc.subjects()。其中(x=>(字符串)x.Attribute(“TextField”)==“menu”).FirstOrDefault();
foreach(menu.Elements()中的XElement元素)
{
string textField=(string)element.Attribute(“textField”);
foreach(element.Elements()中的XElement子元素)
{
List textStrings=subElement.genderantnodesandself().Select(x=>(string)((XElement)x).Attribute(“TextField”).ToList();
textStrings.Insert(0,textField);
Console.WriteLine(string.Join(“>”,textStrings));
}
}
Console.ReadLine();
}
}
}

如果您想独立于菜单的深度,可以选择递归:

IEnumerable<string> GetMenuTexts(XElement menuElement) {
    string ownText = menuElement.Attribute("TextField").Value;
    if (!menuElement.Elements("Menu").Any()) {
        return new string[] { ownText };
    }
    else {
        var menus =
            from subMenuElement in menuElement.Elements("Menu")
            from menuText in GetMenuTexts(subMenuElement)
            select ownText + " > " + menuText;
        return menus;
    }
}
如果不想打印根菜单,则必须从根菜单下的元素开始:

var menus = (from menuElement in XDocument.Parse(xml).Root.Elements("Menu")
            from menuText in GetMenuTexts(menuElement)
            select new
                {
                    TextField = menuText
                }).ToList();

如果您想独立于菜单的深度,可以选择递归:

IEnumerable<string> GetMenuTexts(XElement menuElement) {
    string ownText = menuElement.Attribute("TextField").Value;
    if (!menuElement.Elements("Menu").Any()) {
        return new string[] { ownText };
    }
    else {
        var menus =
            from subMenuElement in menuElement.Elements("Menu")
            from menuText in GetMenuTexts(subMenuElement)
            select ownText + " > " + menuText;
        return menus;
    }
}
如果不想打印根菜单,则必须从根菜单下的元素开始:

var menus = (from menuElement in XDocument.Parse(xml).Root.Elements("Menu")
            from menuText in GetMenuTexts(menuElement)
            select new
                {
                    TextField = menuText
                }).ToList();

这是我见过的最漂亮的答案之一。但是这个打印的答案是:批准>假期/假期>假期预申请批准>假期批准,但是我想要的答案是批准>假期/假期>假期预申请批准批准>假期/假期>假期批准如果Sefe没有给你代码。我可以修改。要获得预期的结果,我需要修改代码以使用递归方法()。Sefe解决方案正在按预期工作。您还可以添加一个答案。让我查一查。谢谢你的提问。这是我见过的最漂亮的答案之一。但是这个打印的答案是:批准>假期/假期>假期预申请批准>假期批准,但是我想要的答案是批准>假期/假期>假期预申请批准批准>假期/假期>假期批准如果Sefe没有给你代码。我可以修改。要获得预期的结果,我需要修改代码以使用递归方法()。Sefe解决方案正在按预期工作。您还可以添加一个答案。让我查一查。感谢您的提问。无法从“System.Collections.Generic.IEnumerable”转换为“System.Xml.Linq.XElement”太棒了!它还打印菜单。我不想在列表中打印。知道吗?它还打印作为参数传递的元素的文本。如果你不想那样,请检查我的编辑。太好了!谢谢!:-)无法从“System.Collections.Generic.IEnumerable”转换为“System.Xml.Linq.XElement”!它还打印菜单。我不想在列表中打印。知道吗?它还打印作为参数传递的元素的文本。如果你不想那样,请检查我的编辑。太好了!谢谢!:-)