如何加载内联DTD以供XDocument使用?

4

我有一个问题,关于如何将文档类型定义包含到XML文件中或从XML文件中加载到WP7的XDocument中。我有一个类似于这样的DTD文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
 <!ELEMENT root (Person*)>

 <!ELEMENT Person (Name*, Description*)>
 <!ELEMENT Name (#PCDATA)>
 <!ELEMENT Description (#PCDATA)>

 <!ENTITY egrave "&#232;">
 <!ENTITY eacute "&#233;">
 <!ENTITY euro  "&#8364;">
]>

我需要将此DTD添加到获取的XML中,以捕获特殊字符,例如&eacute;。 我正在使用以下方法从Web获取XML以在Linq中使用:

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
  string documentUrl = "http://www.example.com";

  WebClient client = new WebClient();

  client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
  client.OpenReadAsync(new Uri(documentUrl, UriKind.Absolute));
}

void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
  Stream str = e.Result;

  XDocument data = XDocument.Load(str);

  // Saving the XML to the file system for later use
  IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication();
  IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("my.xml", FileMode.OpenOrCreate, isoFile);
  StreamWriter sw = new StreamWriter(isoStream);
  XmlWriter xw = XmlWriter.Create(isoStream);

  data.Save(xw);

  // Creating a list to populate a listbox
  List<MyObject> list1 = new List<MyObject>();

  items = (from query in data.Descendants("Person")
    select new MyObject()
    {
    // Doing stuff here...
    }).ToList();

  listBox1.ItemsSource = items;

}

看起来如果DTD放在XML中,即实际的XML本身中,XDocument不会传递XML。 我已经尝试了很多使用基于帖子的XDocumentType的方法,但我无法弄清楚。 我该如何做到这一点?


MSDN确实有针对WP7的专用论坛:http://forums.create.msdn.com/forums/ - Matt Lacey
1
请不要让我们点击到MSDN论坛去阅读问题。请在此处重新提出完整的问题和相关代码。 - ctacke
1个回答

5

读取XML文档时,需要启用DTD处理。为此,请使用适当的设置XmlReader

var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
XmlReader reader = XmlReader.Create(str, settings);
XDocument data = XDocument.Load(reader);

如果您想要使用外部DTD,需要在设置中指定一个XmlResolver:

如果您想要使用外部DTD,需要在设置中指定一个XmlResolver

var settings = new XmlReaderSettings
{
    DtdProcessing = DtdProcessing.Parse,
    XmlResolver = /* some resolver here */,
};

默认的XmlResolver是一个不使用凭据解析URL的XmlUrlResolver。您可能希望考虑从本地源中解析DTD。为此,您可以使用预加载的XmlPreloadedResolver

这是有意义的,无论我是否内联DTD都没有关系。我尝试了这个,但仍然从堆栈跟踪中得到错误:Message=NotSupportedException StackTrace: at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl() at System.Xml.XmlTextReaderImpl.ParseDocumentContent() at System.Xml.XmlTextReaderImpl.Read() at System.Xml.Linq.XDeclaration..ctor(XmlReader r) at System.Xml.Linq.XDocument.Load(XmlReader reader, LoadOptions options) <- 我在这个注释中能够适应的尽可能多。 - Graham How
这种情况是内联 DTD 和外部 DTD 都会发生吗?嗯,我原以为支持这个功能。明天我需要仔细检查一下我们在工作中是怎么做的。 - R. Martinho Fernandes
1
更新:删除内联DTD并包含特殊字符=异常;删除特殊字符并包含内联DTD=异常;删除内联DTD和特殊字符=OK。 - Graham How

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接