我有一个像这样的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<Admin>
<Name>function1</Name>
<Id>1</Id>
<Value>True</Value>
<Name>function2</Name>
<Id>2</Id>
<Value>False</Value>
.
.
.
<Name>functionN</Name>
<Id>N</Id>
<Value>False</Value>
</Admin>
我想将这个文件加载到这样的字典结构中:
Dictionary<AccessPoint, bool>
AccessPoint是一个类:
public class AccessPoint
{
public int Id { get; set; }
public string Name { get; set; }
}
那么如何将xml的每一部分放在较短的代码中的正确位置?
这是我到目前为止所做的:
using (XmlReader reader = new XmlTextReader(path))
{
XmlDocument doc = new XmlDocument();
doc.Load(reader);
XmlNodeList nodeList = doc.ChildNodes;
foreach (XmlNode node in nodeList)
{
var xmlValue = new Dictionary<string, string>();
foreach (XmlNode child in node.ChildNodes)
{
xmlValue[child.LocalName] = child.InnerText;
}
entityInfo.Add(xmlValue);
}
}
但是,entityInfo只收集xml文件的最后一个单位值:
{[Value, False]}
{[Id, N]}
{[Name, FunctionN]}
答案 0 :(得分:0)
你可以编写一个XPath查询来获得你想要的东西,但如果你这样做的话,得到你想要的东西可能更容易(性能更高!):
class AccessPoint
{
public string Name { get ; set ; }
public int Id { get ; set ; }
public bool Value { get ; set ; }
}
static IEnumerable<AccessPoint> AccessPointsFromXml( XDocument doc )
{
AccessPoint item = null ;
foreach( XElement e in doc.Root.Elements() )
{
switch ( e.Name.LocalName )
{
case "Name" :
if ( item != null ) yield return item ;
item = new AccessPoint{ Name = e.Value , } ;
break ;
case "Id" :
int id ;
int.TryParse(e.Value,out id) ;
if ( item == null ) item = new AccessPoint() ;
item.Id = id ;
break ;
case "Value" :
bool value ;
bool.TryParse(e.Value,out value) ;
if ( item == null ) item = new AccessPoint() ;
item.Value = value ;
break ;
}
}
// take care of the last item (if there is one)
if ( item != null ) yield return item ;
}
然后构建字典很简单:
string xml = @"
<?xml version=""1.0"" encoding=""utf-8""?>
<Admin>
<Name>function1</Name>
<Id>1</Id>
<Value>True</Value>
<Name>function2</Name>
<Id>2</Id>
<Value>False</Value>
<Name>function3</Name>
<Id>3</Id>
<Value>False</Value>
</Admin>
".Trim() ;
XDocument doc = XDocument.Load( new StringReader(xml) ) ;
Dictionary<AccessPoint,bool> dict = AccessPointsFromXml(doc)
.ToDictionary( x => x , x => x.Value )
;
编辑注:
使用XmlDocument
XDocument
的{{1}}版本不会改变很多事情:
static IEnumerable<AccessPoint> AccessPointsFromXml( XmlDocument doc )
{
AccessPoint item = null ;
foreach( XmlElement e in doc.DocumentElement.ChildNodes )
{
switch ( e.LocalName )
{
case "Name" :
if ( item != null ) yield return item ;
item = new AccessPoint{ Name = e.InnerText } ;
break ;
case "Id" :
int id ;
int.TryParse(e.InnerText,out id) ;
if ( item == null ) item = new AccessPoint() ;
item.Id = id ;
break ;
case "Value" :
bool value ;
bool.TryParse(e.InnerText,out value) ;
if ( item == null ) item = new AccessPoint() ;
item.Value = value ;
break ;
}
}
if ( item != null ) yield return item ;
}
需要注意的其他事项:您可能希望将AccessPoint
类工具设为IComparable<AccessPoint>
,这样您的字典就会更像您的预期:
class AccessPoint : IComparable<AccessPoint>
{
public string Name { get ; set ; }
public int Id { get ; set ; }
public bool Value { get ; set ; }
public int CompareTo( AccessPoint other )
{
int cc = other != null ? 0 : -1 ;
if ( cc == 0 )
{
cc = String.Compare( this.Name , other.Name , StringComparison.Ordinal ) ;
}
if ( cc == 0 )
{
cc = this.Id.CompareTo( other.Id ) ;
}
return cc ;
}
public override string ToString()
{
return string.Format( "name={0}, id={1}, value={2}" , Name,Id,Value ) ;
}
}