【问题标题】:C# LINQ TO XML - Remove "[]" characters from the DTD headerC# LINQ TO XML - 从 DTD 标头中删除“[]”字符
【发布时间】:2012-09-10 19:17:57
【问题描述】:

我最近在 VS2010 中创建了一个小型 C# windows forms/LINQ to XML 应用程序,它完全按照它应该做的事情,除了一件事:它在 DOCTYPE 标记的末尾添加了“[]”,这显然是导致被遗留系统拒绝的文件。这是之前和之后:

之前

<!DOCTYPE ichicsr SYSTEM "http://www.accessdata.fda.gov/xml/icsr-xml-v2.1.dtd">

之后

<!DOCTYPE ichicsr SYSTEM "http://www.accessdata.fda.gov/xml/icsr-xml-v2.1.dtd"[]>

这些字符是在使用 .Save 函数将文件保存在程序中后添加的。该程序允许选择 .xml 文件,然后通过删除某些标签来“清理”它,然后保存它。当该过程开始时,文件在 DOCTYPE 中没有“[]”。保存后,他们会这样做。 LINQ to XML 会添加这些吗?

有什么方法可以阻止程序添加这些字符?

【问题讨论】:

  • Linq 不太可能自动添加任何内容。你为什么不把这个问题的一个小例子放在一起并在这里发布呢?

标签: c# xml visual-studio-2010 linq-to-xml


【解决方案1】:

显然,当XDocument 解析包含文档类型声明的 XML 文档时,如果不存在空的“内部子集”,则会自动插入该文档。 (内部子集是&lt;!DOCTYPE&gt;[]包围的部分)。

结果是格式良好的 XML。但是,如果您的旧系统无法处理它,您可以通过将 XDocumentType.InternalSubset 属性设置为 null 来从 DTD 中删除内部子集:

XDocument document = ...;
if (document.DocumentType != null)
    document.DocumentType.InternalSubset = null;

【讨论】:

  • 谢谢!这似乎已经做到了。到目前为止,它通过了所有测试。
  • 请注意,这目前在 Mono (2.10.9) 中不起作用,因为您不能将 null 分配给 InternalSubset,尽管您可以指定 null重新创建一个新的XDocumentType。在解析/保存Info.plist 时,这会导致一个catch-22:在文件中输出[] 将导致MonoTouch 中的编译失败。使用空的内部子集加载 Info.plist 会导致发出 [],并且您无法设置 .InternalSubset = null。而XDocument.DocumentType 是只读的。我有祸了!
  • 我遇到了同样的事情(在 mac 上使用 mono 来修改 Info.plist)。在您使用 XDocument 完成工作后,我找到了一个使用 XmlDocument 修改 DOCTYPE 的不错的解决方法,并将其发布在下面。在我发现它之前,我正要进行一些糟糕的字符串替换或求助于 - 颤抖 - XmlReader/XmlWriter。
  • InternalSubsetnull,但一些 XmlWriter (XDocument.Save(Response.Output)) 仍然输出 []。实在想不通。
  • @AlexKamburov:用您的代码发布一个新问题,并包含您所针对的 .NET 版本。
【解决方案2】:

如果您在 Mono(如 cod3monk3y)上处理此问题,例如修改 Info.plist,您可以在使用 XDocument 创建/修改您的 xml 文件后使用旧的 XmlDocument 类进行修复。

代码假定您的“Info.plist”文件位于路径 infoPlist:

using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

var xDocument = XDocument.Load (infoPlist);
// Do your manipulations here
xDocument.Save (infoPlist);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load (infoPlist);
if (xmlDocument.DocumentType != null)
{
    var name = xmlDocument.DocumentType.Name;
    var publicId = xmlDocument.DocumentType.PublicId;
    var systemId = xmlDocument.DocumentType.SystemId;
    var parent = xmlDocument.DocumentType.ParentNode;
    var documentTypeWithNullInternalSubset = xmlDocument.CreateDocumentType(name, publicId, systemId, null);
    parent.ReplaceChild(documentTypeWithNullInternalSubset, xmlDocument.DocumentType);
}
xmlDocument.Save (infoPlist);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多