Как загрузить встроенный DTD для использования с XDocument?
У меня есть вопрос относительно того, как включить определение типа документа в файл XML или из файла XML, который загружается в XDocument, в WP7. У меня есть файл 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 "è">
<!ENTITY eacute "é">
<!ENTITY euro "€">
]>
Мне нужно добавить этот DTD в XML, который я получаю, чтобы ловить специальные символы, такие как é
, Я получаю 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;
}
Кажется, что XDocument не пропустит XML, если DTD помещен в строку, то есть в сам фактический XML. Я попробовал много способов использования XDocumentType на основе этого поста, но я не могу понять это. Как я могу это сделать?
1 ответ
Вам нужно включить обработку DTD, когда вы читаете документ XML. Для этого используйте XmlReader
с соответствующими настройками:
var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
XmlReader reader = XmlReader.Create(str, settings);
XDocument data = XDocument.Load(reader);
Если вы хотите иметь внешний DTD, вам нужно указать XmlResolver
в настройках:
var settings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Parse,
XmlResolver = /* some resolver here */,
};
По умолчанию XmlResolver
является XmlUrlResolver
который разрешает URL-адреса без использования учетных данных. Возможно, вы захотите рассмотреть разрешение DTD из локального источника. Для этого вы можете использовать предварительно заполненный XmlPreloadedResolver
,