我在将我发现的示例翻译成 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
我建议从 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}");
}
}
}
这是一个工作示例。