动态 LINQ 到 XML
Dynamic LINQ to XML
我正在尝试使用 Dynamic LINQ Expressions with LINQ to XML,但在使用动态参数时遇到问题。
这是来自 Dynamic LINQ Wiki 的示例查询:
var query = db.Customers
.Where("City == @0 and Orders.Count >= @1", "London", 10)
.OrderBy("CompanyName")
.Select("new(CompanyName as Name, Phone)");
以我为例,我正在尝试查询以下结构:
<DataCenter>
<Server IP="1.2.3.4">
<OS>Windows</OS>
</Server>
<Server IP="5.6.7.8">
<OS>Linux</OS>
</Server>
</DataCenter>
我正在尝试像这样阅读和解析它:
XElement XmlSource = XElement.Load(filePath)
var query = XmlSource.Elements().AsQueryable().Select("???????");
我应该把什么作为字符串参数?例如,如果我尝试检索所有服务器的 IP 和 OS。当我尝试使用 XElement 的 Element( )
或 Attribute( )
方法时,出现错误“XElement 没有这样的 属性 或方法 ”。
尽管 firstAtteibute
和 firstNode
似乎可用。像这样的东西有效:
var query = XmlSource.Elements()
.AsQueryable()
.Select("new (FirstAttribute.Value as IP, FirstNode.toString() as OS)");
检索属性和后代元素您可以尝试以下代码:
string StringXML = @"<DataCenter>
<Server IP='1.2.3.4'>
<OS>Windows</OS>
</Server>
<Server IP='5.6.7.8'>
<OS>Linux</OS>
</Server>
</DataCenter>";
XDocument Doc = XDocument.Parse(StringXML);
var nodess = from Servers in Doc.Descendants("Server")
select new{IP = Servers.Attribute("IP").Value , OS=Servers.Element("OS").Value} ;
foreach(var node in nodess)
{
Console.WriteLine("ServerIP:"+node.IP + " ServerOS:" +node.OS);
}
string xml =
"<DataCenter><Server IP=\"1.2.3.4\"><OS>Windows</OS></Server><Server IP=\"5.6.7.8\"><OS>Linux</OS></Server></DataCenter>";
XDocument doc = XDocument.Parse(xml);
var servers = doc.Elements("DataCenter").Elements("Server");
var results = from s in doc.Elements("DataCenter").Elements("Server") where (string)s.Attribute("IP") == "1.2.3.4" select s;
编辑:
因为它是 XML,我们想要 elements/attributes 的值,为什么不直接获取它们的 Value
属性。那么就没有理由去处理可访问的类型了。
XDocument doc2 = XDocument.Parse(xml);
var results = from s in doc2.Descendants("Server") select new { OsName = s.Element("OS").Value, IpAddress = s.Attribute("IP").Value };
假设您使用的是 System.Linq.Dynamic.Core
,您可以将 XName
和 XElement
添加到 可访问类型 中,这样它们就可以工作了:
public class MyCustomTypeProvider : DefaultDynamicLinqCustomTypeProvider {
public override HashSet<Type> GetCustomTypes() => new[] { typeof(XName), typeof(XElement) }.ToHashSet();
}
由于 Dynamic LINQ 不使用隐式转换进行方法查找,并且不理解显式转换,因此我展示了两种不同的方法来处理通常由隐式完成的 string
到 XName
的转换转换:
ParsingConfig.Default.CustomTypeProvider = new MyCustomTypeProvider();
var OSName = (XName)"OS";
var query = XmlSource.Elements().AsQueryable()
.Select("new (Attribute(XName.Get(\"IP\")).Value as IP, Element(@0).Value as OS)", OSName);
如果元素 OS
可能缺失,您必须测试 null
。不幸的是,我无法让 np
谓词起作用:
var query = XmlSource.Elements().AsQueryable()
.Select("new (Attribute(XName.Get(\"IP\")).Value as IP, (Element(@0) != null ? Element(@0).Value : null) as OS)", OSName);
我正在尝试使用 Dynamic LINQ Expressions with LINQ to XML,但在使用动态参数时遇到问题。
这是来自 Dynamic LINQ Wiki 的示例查询:
var query = db.Customers
.Where("City == @0 and Orders.Count >= @1", "London", 10)
.OrderBy("CompanyName")
.Select("new(CompanyName as Name, Phone)");
以我为例,我正在尝试查询以下结构:
<DataCenter>
<Server IP="1.2.3.4">
<OS>Windows</OS>
</Server>
<Server IP="5.6.7.8">
<OS>Linux</OS>
</Server>
</DataCenter>
我正在尝试像这样阅读和解析它:
XElement XmlSource = XElement.Load(filePath)
var query = XmlSource.Elements().AsQueryable().Select("???????");
我应该把什么作为字符串参数?例如,如果我尝试检索所有服务器的 IP 和 OS。当我尝试使用 XElement 的 Element( )
或 Attribute( )
方法时,出现错误“XElement 没有这样的 属性 或方法 ”。
尽管 firstAtteibute
和 firstNode
似乎可用。像这样的东西有效:
var query = XmlSource.Elements()
.AsQueryable()
.Select("new (FirstAttribute.Value as IP, FirstNode.toString() as OS)");
检索属性和后代元素您可以尝试以下代码:
string StringXML = @"<DataCenter>
<Server IP='1.2.3.4'>
<OS>Windows</OS>
</Server>
<Server IP='5.6.7.8'>
<OS>Linux</OS>
</Server>
</DataCenter>";
XDocument Doc = XDocument.Parse(StringXML);
var nodess = from Servers in Doc.Descendants("Server")
select new{IP = Servers.Attribute("IP").Value , OS=Servers.Element("OS").Value} ;
foreach(var node in nodess)
{
Console.WriteLine("ServerIP:"+node.IP + " ServerOS:" +node.OS);
}
string xml =
"<DataCenter><Server IP=\"1.2.3.4\"><OS>Windows</OS></Server><Server IP=\"5.6.7.8\"><OS>Linux</OS></Server></DataCenter>";
XDocument doc = XDocument.Parse(xml);
var servers = doc.Elements("DataCenter").Elements("Server");
var results = from s in doc.Elements("DataCenter").Elements("Server") where (string)s.Attribute("IP") == "1.2.3.4" select s;
编辑:
因为它是 XML,我们想要 elements/attributes 的值,为什么不直接获取它们的 Value
属性。那么就没有理由去处理可访问的类型了。
XDocument doc2 = XDocument.Parse(xml);
var results = from s in doc2.Descendants("Server") select new { OsName = s.Element("OS").Value, IpAddress = s.Attribute("IP").Value };
假设您使用的是 System.Linq.Dynamic.Core
,您可以将 XName
和 XElement
添加到 可访问类型 中,这样它们就可以工作了:
public class MyCustomTypeProvider : DefaultDynamicLinqCustomTypeProvider {
public override HashSet<Type> GetCustomTypes() => new[] { typeof(XName), typeof(XElement) }.ToHashSet();
}
由于 Dynamic LINQ 不使用隐式转换进行方法查找,并且不理解显式转换,因此我展示了两种不同的方法来处理通常由隐式完成的 string
到 XName
的转换转换:
ParsingConfig.Default.CustomTypeProvider = new MyCustomTypeProvider();
var OSName = (XName)"OS";
var query = XmlSource.Elements().AsQueryable()
.Select("new (Attribute(XName.Get(\"IP\")).Value as IP, Element(@0).Value as OS)", OSName);
如果元素 OS
可能缺失,您必须测试 null
。不幸的是,我无法让 np
谓词起作用:
var query = XmlSource.Elements().AsQueryable()
.Select("new (Attribute(XName.Get(\"IP\")).Value as IP, (Element(@0) != null ? Element(@0).Value : null) as OS)", OSName);