Linq xElement read - 我需要在读取嵌套依赖项时读取 parent 值

Linq xElement read - I need to read a parent value whilst reading nested dependencies

如标​​题所示,我需要在选择依赖值时读取 parent 值。在将符号加载到 collection 中时,我还需要为每个符号添加 'CategoryDescription' 值。

我用来读取交易品种数据的代码是这样的,但我不知道如何添加 'CategoryDescription' 值。如果可以的话,我不想将它作为另一个元素添加到 Symbol 下。

谢谢,吉姆

    private void UserCategories_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        //
        if (e.AddedItems.Count <= 0) return;

        _userSymbolEntries.Clear();

        var categorySet = UserCategories.SelectedItem.ToString();

        var categx = XElement.Load(catLoadLocation);

        var catResults = categx.Descendants("Category")

            .Descendants("CategoryDescription")
            //.Where(ee => ee.Value == categorySet)
            .Select(ee => ee.Parent)
            .Descendants("Symbol")
            .Select(ee => new
            {
                xDescription = ee.Descendants("Description").FirstOrDefault().Value,
                xFontFamily = ee.Descendants("FontFamily").FirstOrDefault().Value,
                xUnicodeValue = ee.Descendants("UnicodeValue").FirstOrDefault().Value,
                xText = (ee.Descendants("UnicodeValue").FirstOrDefault().Value).ToString(),
                xState = ee.Descendants("UserSymbolState").FirstOrDefault().Value
            });

        var i = 0;
        foreach (var catResult in catResults)
        {
            var use = new UserSymbolEntry {Description = catResult.xDescription};
            TypeConverter tc = TypeDescriptor.GetConverter(typeof(FontFamily));
            use.FontFamily = (FontFamily)tc.ConvertFromString(catResult.xFontFamily);
            use.UnicodeValue = catResult.xUnicodeValue;
            var x = "0x" + catResult.xUnicodeValue;  //    0x0041;  ((char) x).ToString();
            var y = Convert.ToInt32(x, 16);

            switch (catResult.xState)
            {
                case "Normal":
                    use.UserSymbolState = UserSymbolState.Normal;
                    break;

                case "Added":
                    use.UserSymbolState = UserSymbolState.Added;
                    break;

                case "Deleted":
                    use.UserSymbolState = UserSymbolState.Deleted;
                    break;
            }

            use.Text = ((char)y).ToString();
            use.Id = i++;
            if (catResult.xFontFamily == categorySet)
                _userSymbolEntries.Add(use);

        }
    }

XML 看起来像这样

<?xml version="1.0" encoding="utf-8" ?>
<CMCategories>
  <Category>
    <Name>Test</Name>
    <CategoryDescription>FontFamily Change</CategoryDescription>
    <Symbol>
      <Description>A</Description>
      <FontFamily>Courier New</FontFamily>
      <UnicodeValue>0041</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>A</Description>
      <FontFamily>Vani</FontFamily>
      <UnicodeValue>0041</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>A</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>0041</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
  </Category>
  <Category>
    <Name>Arrows</Name>
    <CategoryDescription>Various Arrows</CategoryDescription>
    <Symbol>
      <Description>Left Arrow</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>2190</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>Up Arrow</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>2191</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>Right Arrow</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>2192</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>Down Arrow</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>2193</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
  </Category>
  <Category>
    <Name>MiscTech</Name>
    <CategoryDescription>Miscellaneous Technical</CategoryDescription>
    <Symbol>
      <Description>Double Right</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>23E9</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>Double Left</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>23EA</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>Double Up</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>23EB</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
    <Symbol>
      <Description>Double Down</Description>
      <FontFamily>Segoe UI Symbol</FontFamily>
      <UnicodeValue>23EC</UnicodeValue>
      <UserSymbolState>Normal</UserSymbolState>
    </Symbol>
  </Category>
</CMCategories>

试试这个

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 results = doc.Descendants("Category").Select(x => new {
                name = (string)x.Element("Name"),
                categoryDescription = (string)x.Element("CategoryDescription"),
                symbols = x.Elements("Symbol").Select(y => new {
                    description = (string)y.Element("Description"),
                    fontFamily = (string)y.Element("FontFamily"),
                    unicodeValue = int.Parse((string)y.Element("UnicodeValue"), System.Globalization.NumberStyles.HexNumber),
                    userSymbolState = (string)y.Element("UserSymbolState")
                }).ToList()
            }).ToList();
        }
    }
}