使用C#Regular表达式替换XML元素内容
我正在编写一些处理日志记录xml数据的代码,我希望能够替换文档中某些元素(例如密码)的内容。 我宁愿不序列化和解析文档,因为我的代码将处理各种模式。
样本输入文件:
doc#1:
jsmith myPword
doc#2:
jsmith myPword
我希望我的输出是:
输出文档#1:
jsmith XXXXX
输出文档#2:
jsmith XXXXX
由于我将要处理的文档可能有各种模式,我希望能够找到一个很好的通用正则表达式解决方案,它可以找到带有密码的元素并相应地屏蔽内容。
我可以使用正则表达式和C#解决这个问题,还是有更有效的方法?
使用XSLT可以最好地解决此问题:
XXXXX
只要正确处理命名空间,这将适用于两个输入。
编辑:通过“正确处理命名空间”澄清我的意思
确保具有ns
名称前缀的源文档具有为文档定义的命名空间,如下所示:
jsmith XXXXX
我会说你最好用.NET XmlDocument对象解析内容并使用XPath查找密码元素,然后改变它们的innerXML属性。 它具有更正确的优点(因为XML首先不是常规的),并且它在概念上很容易理解。
根据尝试解析和/或修改XML而没有适当解析器的系统的经验,让我说: 不要做 。 使用XML解析器(这里有其他答案可以快速,轻松地完成此操作)。
使用非xml方法来解析和/或修改XML流将始终会让您在将来的某个时刻感到痛苦。 我知道,因为我感到痛苦。
我知道如果你使用正则表达式解决方案,它似乎会更快 – 运行时/更简单 – 代码/更容易理解/无论如何。 但是你以后只会让别人的生活变得悲惨。
如果您对自己要匹配的内容有足够的了解,则可以使用正则表达式。 例如,如果您正在查找其中没有内部标记的任何标记“password”,则此正则表达式将起作用:
(<([^>]*?password[^>]*?)>)([^<]*?)(<\/\2>)
您可以在zowat的答案中使用相同的C#替换语句,但对于替换字符串,您可能希望使用“$ 1XXXXX $ 4”。
正则表达式是错误的方法,我已经看到它在你最不期望它时会出现如此严重的错误。
无论如何,XDocument更有趣:
XDocument doc = XDocument.Parse(@" jsmith password "); doc.Element("user").Element("password").Value = "XXXX"; // Temp namespace just for the purposes of the example - XDocument doc2 = XDocument.Parse(@" jsmith password "); doc2.Element("secinfo").Element("{http://tempuru.org/users}password").Value = "XXXXX";
这是我在使用XMLDocument时提出的,它可能不像XSLT那样灵活,但应该足够通用以处理各种文档:
//input is a String with some valid XML XmlDocument doc = new XmlDocument(); doc.LoadXml(input); XmlNodeList nodeList = doc.SelectNodes("//*"); foreach (XmlNode node in nodeList) { if (node.Name.ToUpper().Contains("PASSWORD")) { node.InnerText = "XXXX"; } else if (node.Attributes.Count > 0) { foreach (XmlAttribute a in node.Attributes) { if (a.LocalName.ToUpper().Contains("PASSWORD")) { a.InnerText = "XXXXX"; } } } }
XSLT存在的主要原因是能够转换XML结构,这意味着XSLT是一种样式表,可用于改变元素的顺序和更改元素的内容。 因此,这是一个典型的情况,强烈建议使用XSLT而不是解析,正如Andrew Hare在之前的post中所说的那样。