熊哥实现的比较通用的类似XPath查询函数,记录一下。
参考:Linq To Xml实现类似XPath查询
忘了说明一下:Silverlight不支持XPath查询,只能变通一下了。
大气象
public
static
IEnumerable
<
XElement
>
Find(
string
data,
string
node)
{
var test = XDocument.Parse(data);
IEnumerable < XElement > find = null ;
if ( string .IsNullOrEmpty(node) || ! node.StartsWith( @" \\ " )) return null ;
string [] list = node.Substring( 2 ).Split( ' \\ ' );
if ( string .IsNullOrEmpty(list[ 0 ])) return test.Descendants();
string [] attr = null ; string nodeName = string .Empty;
foreach ( string info in list)
{
if (info.IndexOf( " [ " ) != - 1 && info.IndexOf( " ] " ) != - 1 )
{
nodeName = info.Split( ' [ ' )[ 0 ];
attr = info.Split( ' [ ' )[ 1 ].Replace( " ] " , "" ).Replace( " @ " , "" ).Split( ' = ' );
find = find == null ? test.Descendants(nodeName).Where(w => w.Attribute(attr[ 0 ]).Value == attr[ 1 ]).ToList() : find.Descendants(nodeName).Where(w => w.Attribute(attr[ 0 ]).Value == attr[ 1 ]).ToList();
}
else
{
if (find == null ) find = test.Descendants();
find.SelectMany(s => s.Elements(info));
}
}
return find;
}
private void F()
{
string data = @" <?xml version=""1.0"" encoding=""utf-8"" ?><root><o1 id=""1""><o2 id=""1""><o3>5</o3><o3>6</o3></o2><o2 id=""2""><o3>11</o3><o3>22</o3></o2></o1><o1 id=""2""><o2 id=""1""><o3>111</o3><o3>222</o3></o2><o2 id=""2""><o3 id=""1""><o4>2222</o4><o4>3333</o4></o3></o2></o1></root> " ;
// var test = Find(data, @"\\o1[@id=1]\o2[@id=1]\o3");
// var test = Find(data, @"\\o1[@id=1]\o2[@id=2]\o3");
// var test = Find(data, @" \\o1[@id=2]\o2[@id=2]\o3[@id=1]\o4");
var test = Find(data, @" \\o1[@id=2]\o2[@id=2]\o3[@id=1]\o4 " );
if (test != null )
{
foreach (XElement info in test)
{
if (info != null )
Response.Write(info.ToString());
}
}
}
{
var test = XDocument.Parse(data);
IEnumerable < XElement > find = null ;
if ( string .IsNullOrEmpty(node) || ! node.StartsWith( @" \\ " )) return null ;
string [] list = node.Substring( 2 ).Split( ' \\ ' );
if ( string .IsNullOrEmpty(list[ 0 ])) return test.Descendants();
string [] attr = null ; string nodeName = string .Empty;
foreach ( string info in list)
{
if (info.IndexOf( " [ " ) != - 1 && info.IndexOf( " ] " ) != - 1 )
{
nodeName = info.Split( ' [ ' )[ 0 ];
attr = info.Split( ' [ ' )[ 1 ].Replace( " ] " , "" ).Replace( " @ " , "" ).Split( ' = ' );
find = find == null ? test.Descendants(nodeName).Where(w => w.Attribute(attr[ 0 ]).Value == attr[ 1 ]).ToList() : find.Descendants(nodeName).Where(w => w.Attribute(attr[ 0 ]).Value == attr[ 1 ]).ToList();
}
else
{
if (find == null ) find = test.Descendants();
find.SelectMany(s => s.Elements(info));
}
}
return find;
}
private void F()
{
string data = @" <?xml version=""1.0"" encoding=""utf-8"" ?><root><o1 id=""1""><o2 id=""1""><o3>5</o3><o3>6</o3></o2><o2 id=""2""><o3>11</o3><o3>22</o3></o2></o1><o1 id=""2""><o2 id=""1""><o3>111</o3><o3>222</o3></o2><o2 id=""2""><o3 id=""1""><o4>2222</o4><o4>3333</o4></o3></o2></o1></root> " ;
// var test = Find(data, @"\\o1[@id=1]\o2[@id=1]\o3");
// var test = Find(data, @"\\o1[@id=1]\o2[@id=2]\o3");
// var test = Find(data, @" \\o1[@id=2]\o2[@id=2]\o3[@id=1]\o4");
var test = Find(data, @" \\o1[@id=2]\o2[@id=2]\o3[@id=1]\o4 " );
if (test != null )
{
foreach (XElement info in test)
{
if (info != null )
Response.Write(info.ToString());
}
}
}