于是我找解析,可能看起来像这样的XML文件:解析不同父元素下相同类型的XML元素的模式?
<Locations>
<Location Name="California">
<Location Name="Los Angeles">
<Person Name="Harrison Ford"/>
</Location>
</Location>
</Locations>
<People>
<Person Name="Jake Gyllenhaal" Location="Los Angeles"/>
</People>
所以我建立的地点和人员名单。作为一项商业规则,“人”必须与“地点”相关联,但这可以通过以下两种方式之一来完成。可以将它们列为位置元素的子元素,以便他们可以采用该父级位置,或者在People元素下列出时明确列出它们。现在我处理它是这样的(没有任何错误检查)。
public class Parser
{
public void Parse(XElement xmlRoot)
{
IList<Location> locations = new List<Location>();
IList<Person> people = new List<Person>();
var locationParser = new LocationParser();
locations = locationParser.ParseLocations(xmlRoot.Element("Locations"), people);
var peopleParser = new PeopleParser();
people = peopleParser.ParsePeople(xmlRoot.Element("People"), locations);
// Do stuff with XML read objects.
}
}
public class PeopleParser
{
public IList<Person> ParsePeople(XElement peopleRoot, IList<Location> locations)
{
var xPeople = peopleRoot.Elements("Person");
var people = new List<Person>();
foreach (var person in xPeople)
{
var locationName = person.Attribute("Location").Value;
var location = locations.First(loc => loc.Name.Equals(locationName));
people.Add(this.ParsePerson(person, location));
}
return people;
}
public Person ParsePerson(XElement person, Location location)
{
var personName = person.Attribute("Name").Value;
return new Person(personName, location);
}
}
public class LocationParser
{
PeopleParser peopleParser = new PeopleParser();
public IList<Location> ParseLocations(XElement locationRoot, IList<Person> people)
{
var xLocations = locationRoot.Elements("Location");
var locations = new List<Location>();
foreach (var location in xLocations)
{
locations.Add(this.ParseLocation(location, people));
}
return locations;
}
public Location ParseLocation(XElement xLocation, IList<Person> people)
{
var children = new List<Location>();
foreach (var subLocation in xLocation.Elements("Location"))
{
children.Add(this.ParseLocation(subLocation, people));
}
var newLocation = new Location(xLocation.Attribute("Name").Value, children);
foreach (var xPerson in xLocation.Elements("Person"))
{
people.Add(peopleParser.ParsePerson(xPerson, newLocation));
}
return newLocation;
}
}
}
此代码是我“丑”,这只是东西变得更依赖XML类型添加了很多丑陋的一个简单的例子。这是否如此好,还是有一种方法可以重写,以更好地分离关注点?
我不明白你的问题。或者为什么一个人被列为两种不同的方式之一,但基本意义相同。 – 2014-12-11 00:11:16
问题是,这可以解析'更好'说例如让PeopleParser离开LocationParser。至于为什么可以用多种方式定义一个人只是添加选项。我主要是在构建我自己的解析器来寻找已经存在的东西,所以我必须遵循创建者的约定。在Wix工具集中查找示例,其中XML元素(如组件)可以在各种不同的元素下声明。 – Thermonuclear 2014-12-11 00:28:46
您需要在名称旁边的Location对象中存储什么信息?路径也很重要(例如:加州/洛杉矶)? – alexm 2014-12-11 00:49:40