我为每个用户提供了用于管理网站权限的XML,还有一个管理工具可以更新XML以授予/拒绝/修改对新用户或现有用户的访问权
XML的结构类似于
<Security>
<FiscalYear ID="2011">
<Country ID="23">
<State ID="10">
<City ID="1"></City>
<City ID="3"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2010">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
</Security>
现在,如果管理员想要授予新会计年度2012的许可,我将获得这样的输入
<FiscalYear ID="2012">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
因此,这个将作为新节点附加到现有节点 或者如果他想修改现有权限
<FiscalYear ID="2011">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
这个用于修改权限,意味着授予用户访问状态20和城市11和32
的权限我是否可以遵循我的合并数据的最佳方式或示例
答案 0 :(得分:2)
如果您只想附加一个新节点,这很简单:
var xmlDocument = XDocument.Parse(xmlParentStr);
var xmlToAdd = XElement.Parse(xmlToAddStr);
if (null != xmlDocument.Element("Security"))
xmlDocument.Element("Security").AddFirst(xmlToAdd);
其中xmlParentStr是一个字符串,其中包含您首次出现的xml,以及2011和2010 FiscalYear标记。 xmlToAdd是2012年会计年度的xml字符串。这将为您提供:
<Security>
<FiscalYear ID="2012">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2011">
<Country ID="23">
<State ID="10">
<City ID="1"></City>
<City ID="3"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2010">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
</Security>
顺便说一句,还有其他各种方法可以将xml加载到XDocument或XElement中。例如XDocument.Load()和XElement.Load,它们可以从FileStream,URI或Reader中提取它。
如果您想更改2011年的国家/地区ID,可以通过以下方式轻松完成:
var elementToChange=xmlDocument
.Descendants()
.Where(x => x.Name.LocalName=="FiscalYear" && x.Attribute("ID")!=null && x.Attribute("ID").Value=="2011");
foreach(var element in elementToChange) {
var changes = element.Descendants().Where(x => x.Name.LocalName == "Country" && x.Attribute("ID").Value == "23");
foreach(var change in changes) {
change.Attribute("ID").SetValue("1337");
}
}
然后会产生:
<Security>
<FiscalYear ID="2012">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2011">
<Country ID="1337">
<State ID="10">
<City ID="1"></City>
<City ID="3"></City>
</State>
</Country>
</FiscalYear>
<FiscalYear ID="2010">
<Country ID="13">
<State ID="20">
<City ID="11"></City>
<City ID="32"></City>
</State>
</Country>
</FiscalYear>
</Security>
我将您需要的值更改为“1337”,因为它更容易看到,但原理是相同的。你可以继续以这种方式走下树。 (以下代码会更改匹配的每个条目,如果您决定只更改第一个条目或者知道您只有一个,您可以通过使用.FirstOrDefault()来简化上述代码并摆脱foreach循环< / p>
答案 1 :(得分:1)
// untested
var masterDoc = XDocument.Load(...);
var updateDoc = XDocument.Load(...);
foreach (var year in updateDoc.Root.Descendants("FiscalYear"))
{
var oldYear = masterDoc.Root.Descendants("FiscalYear")
.Where(y => y.Attributes["ID"].Value == year.Attributes["ID"].Value)
.FirstOrDefault() ;
if (oldYear == null)
{
masterDoc.Root.Add(new XElement(....));
}
else
{
// nested properties
}
}
答案 2 :(得分:0)
我发布了我的要求的工作版本:)
XDocument currentPermission = XDocument.Parse(xmlParentStr);
XDocument newPermission = XDocument.Load(xmlToAddStr);
int fyValue = 2012, countryId = 205, stateId = 0, cityId = 0;
//check whether user has access for this fiscal year or not
IEnumerable<XElement> fyList = from fyNode in currentPermission.Descendants("FiscalYear")
where (int)fyNode.Attribute("Name") == fyValue
select fyNode;
if (null != fyList && fyList.Count() > 0) //Fiscal year present, means user is trying to modify permissions for the given fiscal year
{
//Check whether user has access for this country or not
IEnumerable<XElement> countryList = from subNode in fyList.Descendants("Country")
where (int)subNode.Attribute("ID") == countryId
select subNode;
if (null != countryList && countryList.Count() > 0) //country present, means user is trying to modify permissions for a country
{
IEnumerable<XElement> stateList = from mbpNode in countryList.Descendants("State")
where (int)mbpNode.Attribute("ID") == stateId
select mbpNode;
if (stateId != 0 && null != stateList && stateList.Count() > 0)
{
IEnumerable<XElement> cityList = from mbpNode in stateList.Descendants("City")
where (int)mbpNode.Attribute("ID") == stateId
select mbpNode;
if (cityId != 0 && null != cityList && cityList.Count() > 0)
{
// User already have access, nothing to do
}
else
{
currentPermission.Elements("FiscalYear")
.Where(t => t.Attribute("Name").Value == fyValue.ToString())
.Elements("Country")
.Where(t => t.Attribute("ID").Value == countryId.ToString())
.Elements("State")
.Where(t => t.Attribute("ID").Value == stateId.ToString())
.Single()
.Add(newPermission.Descendants("City"));
}
}
else
{
currentPermission.Elements("FiscalYear")
.Where(t => t.Attribute("Name").Value == fyValue.ToString())
.Elements("Country")
.Where(t => t.Attribute("ID").Value == countryId.ToString())
.Single()
.Add(newPermission.Descendants("State"));
}
}
else //Country is not present means user is granted permissions for this country
{
currentPermission.Elements("FiscalYear")
.Where(t => t.Attribute("Name").Value == fyValue.ToString())
.Single()
.Add(newPermission.Descendants("Country"));
}
}
else //fiscal year is not present, it means user is trying to add permissions for a new fiscal year
{
//string newPermissionXML = CreatePermissionXML(newUserPermission);
currentPermission.Add(newPermission.Descendants("FiscalYear"));
}