XMLinvalide chars替换C#

时间:2017-07-31 13:13:13

标签: c# xml

我有一个以XML格式显示的字符串,但在其中我有一些无效的字符,如字符串
 s = <root> something here <XMLElement>hello</XMLElement> somethig here too </root>
 其中XMLElement是一个像XMLElement = {“bold”,“italic”,...}的列表 我需要的是替换<</,如果后面跟着被&gt;&lt;取代的任何XMLElements,视情况而定。
<root>是为了保持身份 到目前为止我已尝试过一些regEx

 strAux = Regex.Replace(strAux, "bold=\"[^\"]*\"",
match => match.Value.Replace("<", "&lt;").Replace(">", "&gt;"));

 List<string> startsWith = new List<string> { "<", "</"};
        foreach(var stw in startsWith)
        {
            int nextLt = 0;
            while ((nextLt = strAux.IndexOf(stw, nextLt)) != -1)
            {
                bool isMatch = strAux.Substring(nextLt + 1).StartsWith(BoldElement); // needs to ckeck all  the XMLElements
                //is element, leave it
                if (isMatch)
                {
                    //its not, replace
                    strAux = string.Format(@"{0}&lt;{1}", strAux.Substring(0, nextLt), strAux.Substring(nextLt +1, strAux.Length - (nextLt + 1)));
                }
                nextLt++;
            }
        }

也试过

XmlDocument doc = new XmlDocument();
            XmlElement element = doc.CreateElement("root");
            element.InnerText = strAux;
            Console.WriteLine(element.OuterXml);
            strAux = element.OuterXml.Replace("&lt;root&gt;", "").Replace("&lt;/root&gt;", "");
            return strAux; But it will repeat the `<root>` too

但没有像我所说的那样有效。有没有不同的想法。谢谢

3 个答案:

答案 0 :(得分:0)

您所拥有的是格式良好的XML,因此您可以使用XML API来帮助您:

使用LINQ to XML(通常是更好的API):

var element = XElement.Parse(s);

element.Value = string.Concat(element.Nodes());

var result = element.ToString();

或使用较早的XmlDocument API:

var doc = new XmlDocument();
doc.LoadXml(s);
var root = doc.DocumentElement;

root.InnerText = root.InnerXml;

var result = root.OuterXml;

两者的结果是:

<root> something here &lt;XMLElement&gt;hello&lt;/XMLElement&gt; somethig here too </root>

请参阅this fiddle了解演示。

答案 1 :(得分:0)

您应该使用XmlWriter类。

文档中的示例:

XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.CloseOutput = false;

// Create the XmlWriter object and write some content.
MemoryStream strm = new MemoryStream();
XmlWriter writer = XmlWriter.Create(strm, settings);
writer.WriteElementString("someNode", "someValue");
writer.Flush();
writer.Close();

https://msdn.microsoft.com/en-us/library/system.xml.xmlwriter(v=vs.110).aspx

答案 2 :(得分:0)

听起来您的输入是格式良好的XML,但您想要转义某些标记。这里的问题是,代码无法知道哪些代码有效且哪些代码无效。

执行此操作的一种方法是创建有效标记列表。

List<string> validTags = new List<string>() { "root", "..." };

然后使用正则表达式挑选<tag></tag>的所有实例,如果它们不在列表中,则替换它们。

另一种更快捷,更简单但需要更多信息的方法是创建有效的标记列表。

List<string> invalidTags = new List<string>() { "XMLElement", "..." };

现在可以进行简单的字符串操作。

string s = GetYourXMLString();
invalidTags.ForEach(t => s = s.Replace($"</{t}>",$"&lt;{t}&gt;")
                          .Replace($"<{t}>",$"&lt;/{t}&gt;"));

如果您知道哪些外国标签正在制作(或将要制作)外观,则应该真正使用第二种方式。如果不是,应该使用第一种方法。一个聪明的可能性是使用反射或数据协定动态创建有效标记列表,以便XML规范的更改将自动反映在您的代码中。

例如,如果每个元素都是对象的属性,则可能会得到如下列表:

var validTags = typeof(MyObjectType).GetProperties()
                                    .Select(p => p.PropertyName)
                                    .ToList();

当然,属性名称可能不会成为实际的标记名称,并且通常您只想包含某些属性。所以你创建了一个属性类来指定所需的属性(让我们称之为XMLTagName)然后你可以这样做:

var validTags = typeof(MyObjectType).GetProperties()
                                    .Select(p => p.GetCustomAttribute<XMLTagName>()?.TagName)
                                    .Where(tagName => tagName != null) //gets rid of properties that aren't tagged
                                    .ToList();

即便如此,您仍然会在原始XML上犯下字符串操作的罪行。毕竟,最佳真正的解决方案是弄清楚如何修复传入的XML以实际包含所需的数据。但如果不可能,那么上述工作就应该完成。