我必须根据某些条件从C#中的XML读取值。下面是我的示例xml
<Properties>
<prop1 Name = " Apple" Defaultvalue="red">
<childprop Name = "special" Value="pink" >
</childprop>
</prop1>
<prop1 Name = " Orange" Defaultvalue="orange">
</prop1>
<prop1 Name = "Banana" Defaultvalue="yellow">
<childprop Name = "raw" Value="green" >
</childprop>
<childprop Name = "special" Value="red" >
</childprop>
</prop1>
</Properties>
例如,如果输入为Orange,则返回值为defaultvalue =“ Orange”
如果输入为香蕉,则返回将基于第二输入。 如果是香蕉,生的,-返回绿色 如果是香蕉,则空白-返回黄色 如果是香蕉,则长整型-返回黄色(“长整型”不匹配,因此返回父级的默认值)。
实现此目标的最佳方法是什么。
答案 0 :(得分:1)
使用Linq2xml帮助您:
var workflowXml = @"
<Properties>
<prop1 Name = ""Apple"" Defaultvalue=""red"">
<childprop Name = ""special"" Value=""pink"" >
</childprop>
</prop1>
<prop1 Name = ""Orange"" Defaultvalue=""orange"">
</prop1>
<prop1 Name = ""Banana"" Defaultvalue=""yellow"">
<childprop Name = ""raw"" Value=""green"" >
</childprop>
<childprop Name = ""special"" Value=""red"" >
</childprop>
</prop1>
</Properties>";
var xmlDoc = XDocument.Parse(workflowXml);
var xmlCurrentLevelElement = xmlDoc.Element("Properties");
var stepNumber = 1;
while (true)
{
var options = xmlCurrentLevelElement
.Elements()
.Select(e => e.Attributes().FirstOrDefault(a => a.Name == "Name"))
.Where(a => a != null)
.ToArray();
if (!options.Any())
{
var currentValue = xmlCurrentLevelElement
.Attributes()
.FirstOrDefault(a => a.Name == "Value" || a.Name == "Defaultvalue")
?.Value ?? "value not defined";
Console.WriteLine($"no more options: {currentValue}");
break;
}
var hints = string.Join(" or ", options.Select(a => a.Value));
Console.WriteLine($"step {stepNumber}: input any value from '{hints}' - ");
var value = Console.ReadLine();
var xmlNextLevelElement = options
.FirstOrDefault(a => a.Value == value)
?.Parent ?? null;
if (xmlNextLevelElement == null)
{
var defaultValue = xmlCurrentLevelElement
.AncestorsAndSelf()
.Select(e => e.Attributes().FirstOrDefault(a => a.Name == "Defaultvalue"))
.Where(a => a != null)
.FirstOrDefault()
?.Value ?? "default value not defined";
Console.WriteLine($"no match: {defaultValue}");
break;
}
xmlCurrentLevelElement = xmlNextLevelElement;
stepNumber++;
}
答案 1 :(得分:1)
另一个LINQ to XML示例。还有对Microsoft Docs的引用。
using System;
using System.Linq;
using System.Xml.Linq;
public class Program
{
public static void Main()
{
Find("Apple");
Find("Banana,raw");
Find("Banana, ");
}
public static void Find(string input)
{
var xml = @"<Properties>
<prop1 Name = ""Apple"" Defaultvalue=""red"">
<childprop Name = ""special"" Value=""pink"" >
</childprop>
</prop1>
<prop1 Name = ""Orange"" Defaultvalue=""orange"">
</prop1>
<prop1 Name = ""Banana"" Defaultvalue=""yellow"">
<childprop Name = ""raw"" Value=""green"" >
</childprop>
<childprop Name = ""special"" Value=""red"" >
</childprop>
</prop1>
</Properties>";
var doc = XElement.Parse(xml);
var keywords = input.Split(',');
XElement match = null;
foreach (var key in keywords){
var node = (from n in (match??doc).Descendants()
where (string)n.Attribute("Name") == key
select n).FirstOrDefault();
match = node??match;
}
if (match != null)
Console.WriteLine(((string) match.Attribute("Defaultvalue"))??((string)match.Attribute("Value")));
else
Console.WriteLine("Nothing Found.");
}
}
在.Net Fiddle中运行
答案 2 :(得分:1)
这里是一个查询版本:
var document = XDocument.Parse(xml);
var dictionaries =
document
.Root
.Elements("prop1")
.Select(prop1 => new
{
name = prop1.Attribute("Name").Value,
children =
prop1
.Elements("childprop")
.Select(childprop => new
{
name = childprop.Attribute("Name").Value,
value = childprop.Attribute("Value").Value
})
.StartWith(new
{
name = "",
value = prop1.Attribute("Defaultvalue").Value
})
})
.ToDictionary(
x => x.name,
x => x.children.ToDictionary(y => y.name, y => y.value));
当我写这篇文章时:
Console.WriteLine(dictionaries["Apple"][""]);
Console.WriteLine(dictionaries["Apple"]["special"]);
Console.WriteLine(dictionaries["Banana"][""]);
Console.WriteLine(dictionaries["Banana"]["raw"]);
Console.WriteLine(dictionaries["Banana"]["special"]);
我明白了:
red pink yellow green red
答案 3 :(得分:0)
使用 Linq
String result = string.Empty;
var exist = xdoc.Descendants("Properties").Descendants("prop1").Attributes("Name").Where(x => x.Value.Equals(value)).FirstOrDefault();
if (exist != null)
{
XElement xElement = xdoc.Descendants("prop1").Where(x => x.Attribute("Name").Value.Equals(value).Select(x => x).FirstOrDefault();
var childPropsExist = xElement.Elements("childprop").Any();
if (childPropsExist) //we will be needing second input
{
result = xElement.Elements("childprop").Attributes("Name").Where(x => x.Value.Equals(secondInput)).FirstOrDefault().NextAttribute.Value;
} else {
result = exist.NextAttribute.Value; //Default value;
}
}
return result;