从 XML 中选择 2 个元素

问题描述 投票:0回答:1

我在将我发现的示例翻译成 XML 使用时遇到了很多麻烦。

从此开始(整个 XML 文件的精简版)

<?xml version="1.0" encoding="UTF-8"?>
<MetadataSets>
     <MetadataSet MetadataSetID="999_never" >
         <MetadataSetItem>
             <TagName>NeverSeen</TagName>
             <ItemSeq>10</ItemSeq>
         </MetadataSetItem>
         <MetadataSetItem>
             <TagName>AlsoNeverSeen</TagName>
             <ItemSeq>20</ItemSeq>
         </MetadataSetItem>
    </MetadataSet>
</MetadataSets>

我想做的是创建一个包含 2 个字段的有序列表,最终我希望以元组列表的形式返回

'NeverSeen'         10
'AlsoNeverSeen'     20

以下是我尝试过的几种方法的列表 - 大部分是为了表明我在寻求帮助之前已经做出了努力。

因此,我希望得到一些帮助,帮助我找到解决这个特定问题的正确路径,但也有人对有关 LINQ for XML 的体面的、不平凡的教程提出建议。

我应该说我来自数据库背景; SQL 需要 30 秒 - XML 和 LINQ 需要 5 天。

我也对不同的方法感到困惑 - 并且可能无意中混合了它们 例如那些使用“from”的

 var schema3 = from el in XDoc.Elements("MetadataDomain")
                     where (String)el.Attribute("DomainUUID") == pDomainUUID
                     select (el) ;  

然后迭代“el”,即使只有一个。

或者那些不使用“from”但使用“.”的

var schema4 = XDoc.Elements("MetadataDomain")
    .Where  (sch => (String)sch.Attribute("DomainUUID") == pDomainUUID)
    .Select (sch => (String)sch.Element("SchemaName").Value );  

那么即使只有一个结果,你仍然需要迭代结果。

我对 XPath 很感兴趣,例如

string schema5 = root.XPathSelectElement($"MetadataSets/MetadataDomain[@DomainUUID='{pDomainUUID}']").Element("SchemaName").Value;

但是放弃了,因为它全部在一行上,所以当它崩溃时,没有办法调试任何东西。几乎您输入的任何内容都会编译。

如何选择 2 个“字段”,例如有人说选择 2 个“字段”使用匿名类型,例如

 select new { car.Make, car.VIN}
 when I try that with XML 
     where (String)el.Attribute("MetadataSetID") == pMetadataSetID
                     select new { el.Element("TagName").Value, el.Element("ItemSeq").Value } ; 

它给出编译错误错误CS0833:匿名类型不能有多个同名属性 似乎编译器无法区分它们,而且我不知道如何给它们起别名。

谢谢 JC

c# xml linq
1个回答
0
投票
  • 我建议从 XML 创建 C# 类(有在线工具可以做到这一点)。

  • 将 XML 序列化到这些类中

  • 使用 Linq 获取结果

    [XmlRoot("MetadataSets")]
    public class MetadataSets
    {
        [XmlElement("MetadataSet")]
        public List<MetadataSet> MetadataSetList { get; set; }
    }
    
    public class MetadataSet
    {
        [XmlAttribute("MetadataSetID")]
        public string MetadataSetID { get; set; }
    
        [XmlElement("MetadataSetItem")]
        public List<MetadataSetItem> MetadataSetItems { get; set; }
    }
    
    public class MetadataSetItem
    {
        [XmlElement("TagName")]
        public string TagName { get; set; }
    
        [XmlElement("ItemSeq")]
        public int ItemSeq { get; set; }
    } 
    
    public class Program
    {
        public static void Main()
        {
            var xml = @"<MetadataSets>
                           <MetadataSet MetadataSetID=""999_never"">
                               <MetadataSetItem>
                                   <TagName>NeverSeen</TagName>
                                   <ItemSeq>10</ItemSeq>
                               </MetadataSetItem>
                               <MetadataSetItem>
                                   <TagName>AlsoNeverSeen</TagName>
                                   <ItemSeq>20</ItemSeq>
                               </MetadataSetItem>
                           </MetadataSet>
                         </MetadataSets>";
    
            var serializer = new XmlSerializer(typeof(MetadataSets));
    
            using var reader = new StringReader(xml);
            var metadataSets = (MetadataSets)serializer.Deserialize(reader);
    
            var items = metadataSets.MetadataSetList.SelectMany(x => x.MetadataSetItems);
    
            foreach(var item in items)
            {
                Console.WriteLine($"{item.TagName} = {item.ItemSeq}");
            }
        }
    }
    

这是一个工作示例

© www.soinside.com 2019 - 2024. All rights reserved.