C# XML中的特殊字符
我想解析以下XMLC# XML中的特殊字符,c#,xml,C#,Xml,我想解析以下XML XmlElement costCenterElement2 = doc.CreateElement("CostCenter"); costCenterElement2.InnerXml = "<CostCenterNumber>2</CostCenterNumber> <CostCenter>" + "G&A: Fin & Acctng" + "</CostCenter>"; 但我发现X
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&A: Fin & 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;")
.Replace(">", "<>gt;")
.Replace("&", "<>amp;")
.Replace("'", "<>apos;")
.Replace(""", "<>quot;");
result = result.Replace("&", "&");
result = result.Replace("<>lt;", "<")
.Replace("<>gt;", ">")
.Replace("<>amp;", "&")
.Replace("<>apos;", "'")
.Replace("<>quot;", """);
return result.ToString();
}