我有一个xml字符串,其中包含我想要屏蔽的某些值。我还有一个黑名单列表,其中包含我想要屏蔽的元素或属性的名称。我怎么能用Linq做到这一点?
var BlackList=new List<string>{"ssn", "dateofbirth"};
var xml=@"<Rows><Row><SSN>123-12-1234</SSN><Address>123 Somewhere Street</Address><DateOfBirth>12-12-2012</DateOfBirth></Row><Row><SSN value=""123-12-1234""/><Address value=""123 Somewhere Street""/><DateOfBirth value=""12-12-2012""/></Row></Rows>";
结果集如下所示:
"<Rows><Row><SSN>RemovedForSecurity</SSN><Address>123 Somewhere Street</Address><DateOfBirth>RemovedForSecurity</DateOfBirth></Row><Row><SSN value="RemovedForSecurity"/><Address value="123 Somewhere Street"/><DateOfBirth value="RemovedForSecurity"/></Row></Rows>"
答案 0 :(得分:5)
首先,使用LINQ to XML获取所有实际的XML。你开始使用字符串并最终得到一个字符串的事实是偶然的:你真的试图操纵XML文档。那时候这很容易:
var redactedElements = new HashSet<XName>
{
"SSN",
"CreditCard"
};
var redactedAttributes = new HashSet<XName>
{
"dateofbirth",
...
};
var elements = doc.Descendants()
.Where(x => redactedElements.Contains(x.Name))
.ToList();
foreach (var element in elements)
{
element.Value = "RemovedForSecurity";
}
var attributes = doc.Descendants()
.Attributes()
.Where(x => redactedAttributes.Contains(x.Name))
.ToList();
foreach (var attribute in attributes)
{
attribute.Value = "RemovedForSecurity";
}
编辑:为了区分大小写,您将保留一个不区分大小写的本地名称列表:
var redactedElements = new HashSet<string>(StringEqualityComparer.OrdinalIgnoreCase);
{
"SSN",
"CreditCard"
};
var elements = doc.Descendants()
.Where(x => redactedElements.Contains(x.Name.LocalName))
.ToList();
// Ditto for the attributes
如果你指定了确切的名字,那会更好,IMO。
答案 1 :(得分:1)
var unsecureElements =
XElement.Parse(xml)
.Descendants()
.Where(n => blackList.Contains(n.Name.LocalName.ToLower()));
foreach (var element in unsecureElements)
{
var valueAttribute = element.Attribute("value");
if (valueAttribute != null) // check if unsecure element has value attribute
valueAttribute.SetValue("RemovedForSecurity");
else
element.Value = "RemovedForSecurity";
}