C# C“LINQ到XML-删除”;[……”是;DTD头中的字符

C# C“LINQ到XML-删除”;[……”是;DTD头中的字符,c#,xml,visual-studio-2010,linq-to-xml,C#,Xml,Visual Studio 2010,Linq To Xml,我最近在VS2010中创建了一个小型的C#windows forms/LINQ to XML应用程序,它完全按照它应该做的做,除了一件事:它在DOCTYPE标记的末尾添加了“[]”,这显然会导致文件被旧系统拒绝。这里有一个前后对比: 以前 <!DOCTYPE ichicsr SYSTEM "http://www.accessdata.fda.gov/xml/icsr-xml-v2.1.dtd"> 之后 使用.Save函数将文件保存到程序中后,将添加这些字符。该程序允许选择一

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

以前

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

之后


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


有没有办法防止程序添加这些字符?

显然,当
XDocument
解析包含文档类型声明的XML文档时,如果不存在空的“内部子集”,则会自动插入一个空的“内部子集”。(内部子集是由
中的
[]
包围的零件)

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

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

如果您在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);

Linq不太可能自动添加任何内容。你为什么不把这个问题的一个小例子放在这里呢?谢谢!这似乎已经做到了。到目前为止,它通过了所有测试。请注意,这在Mono(
2.10.9
)中目前不起作用,因为您不能将null分配给
InternalSubset
,尽管您可以在创建新的
XDocumentType
时指定null。解析/保存
Info.plist
时,这会导致第22条军规:在文件中输出
[]
将导致MonoTouch中的编译失败。使用空的内部子集加载
Info.plist
会导致发出
[]
,并且您无法设置
.InternalSubset=null
。而
XDocument.DocumentType
是只读的。我有祸了!我点击了同样的东西(在mac上使用mono修改Info.plist)。在您使用XDocument完成工作后,我发现了一个使用XmlDocument修改DOCTYPE的不错的解决方法,我将其发布在下面。在找到它之前,我正准备做一些糟糕的字符串替换或求助于-shubder-XmlReader/XmlWriter。
InternalSubset
null
,但一些XmlWriter(
XDocument.Save(Response.Output)
)仍然输出
[]
。我真的搞不懂。@AlexKamburov:用你的代码发布一个新问题,并包括你的目标.NET版本。
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);