C# XML中的特殊字符

C# XML中的特殊字符,c#,xml,C#,Xml,我想解析以下XML XmlElement costCenterElement2 = doc.CreateElement("CostCenter"); costCenterElement2.InnerXml = "<CostCenterNumber>2</CostCenterNumber> <CostCenter>" + "G&A: Fin & Acctng" + "</CostCenter>"; 但我发现X

我想解析以下XML

XmlElement costCenterElement2 = doc.CreateElement("CostCenter");
costCenterElement2.InnerXml =
    "<CostCenterNumber>2</CostCenterNumber> <CostCenter>" +
    "G&A: Fin & Acctng" +
    "</CostCenter>";
但我发现XML异常

分析EntityName时出错

是-a在XML中无效,需要转义到&

其他字符无效字符及其转义:

< - > - -"e; ——&apos; 以下方面应起作用:

XmlElement costCenterElement2 = doc.CreateElement("CostCenter");
costCenterElement2.InnerXml =
  "<CostCenterNumber>2</CostCenterNumber> <CostCenter>" +
  "G&amp;A: Fin &amp; Acctng" +
  "</CostCenter>";
但是,您确实应该将CostCenterNumber和CostCenter创建为元素,而不是InnerXml。

更新:

@thabet,如果字符串…G&A:Fin&Acctng是作为参数输入的,并且它应该表示要解析的XML,那么它首先必须是格式良好的XML。在您给出的示例中,它不是表示实体引用的开始,后跟实体名称,终止于;,它从未出现在上面的字符串中

如果将整个字符串作为参数提供给您,其中一些是必须解析的标记,即开始/结束标记,而其中一些可能包含不应解析的标记,即&,则没有干净可靠的方法来转义后者,而不是转义前者。您可以将所有&;字符替换为&;,但在这样做时,您可能会意外地变成&160;进入&;160; 而你的结果是错误的。如果这是您的情况,即您接收到的输入XML中的标记与不可解析的文本混合在一起,那么最好的办法是告诉您获取XML的人XML格式不正确,他们需要修复其输出。对于他们来说,有一些方法可以做到这一点,而使用标准XML工具并不困难

另一方面,如果你有

<CostCenterNumber>2</CostCenterNumber>
<CostCenter>...</CostCenter>
与传递的字符串分开,并且您需要插入传递的字符串作为子级的文本内容,并且您知道不需要解析的字符串不包含元素,那么您可以执行以下操作:

创建和作为元素 让他们成为父母的孩子 假设没有标记风险,则使用InnerXML设置CostCenterNumber的文本内容:eltcn.InnerXML=2; 为子成本中心元素创建一个文本节点子元素,其值为传递的字符串:textCC=doc.CreateTextargStr; 将该文本节点指定为子CostCenter元素的子元素:eltCC.AppendChildtextCC;
您也可以在这里看一看:了解更多信息。感谢oded的回复,但实际上这个字符串是在方法参数中解析的,我不知道该字符串包含&或任何特殊字符,我需要general来转义所有特殊字符实际>大于XML中允许的值,并且不必转义。但许多人确实逃避了它,因为对称。另外,不是"e;“和”在文本数据中很好,如给定问题中所示。属性值中不允许使用它们。@LarsH-来自规范XML 1.0,第2.4节:直角括号>,可以使用字符串表示,并且为了兼容,必须在内容中使用字符串]]>或字符引用进行转义,当该字符串未标记CDATA节的结束时。很好的一点。。。>确实需要转义时出现罕见的异常。不过,我仍然反对笼统的语句暗示>在XML中无效。@这是一个好主意,尽管它不处理像&160;这样的情况;,或已在文档中定义的非字符实体。true。这只是一次黑客攻击。但我认为没有一个合适的解决办法。不过,这可能会解决老年退休金计划的特定问题。我更新了答案,以澄清如何知道问题何时在上游,何时需要从源头上解决。
        private string SanitizeXml(string source)
        {
            if (string.IsNullOrEmpty(source))
            {
                return source;
            }
            if (source.IndexOf('&') < 0)
            {
                return source;
            }
            StringBuilder result = new StringBuilder(source);
            result = result.Replace("&lt;", "<>lt;")
                            .Replace("&gt;", "<>gt;")
                            .Replace("&amp;", "<>amp;")
                            .Replace("&apos;", "<>apos;")
                            .Replace("&quot;", "<>quot;");
            result = result.Replace("&", "&amp;");
            result = result.Replace("<>lt;", "&lt;")
                            .Replace("<>gt;", "&gt;")
                            .Replace("<>amp;", "&amp;")
                            .Replace("<>apos;", "&apos;")
                            .Replace("<>quot;", "&quot;");

            return result.ToString();
        }