Не могу проверить простой (или сложный) XML с DTD, используя C# и vs2017
Я работал над проблемой, пытаясь проверить документ XML со связанным файлом DTD. Сначала я попытался преобразовать пример из ( статья Micorsoft), а затем прочитал статью в другой статье Stack-Overflow ( здесь). В обоих случаях (действительные и недействительные документы XML) простой XML-файл не проходит проверку, и я не могу понять, почему...
Моим тестовым приложением является проект Windows Forms с одной формой, на которой есть пара кнопок и следующий код...
bool isValid = true;
StringBuilder xml = new StringBuilder();
StringBuilder messages = new StringBuilder();
string nl = Environment.NewLine;
public FormMain()
{
InitializeComponent();
}
private void ValidateProductXMLButton_Click(object sender, EventArgs e)
{
ValidateXML("ProductWithDTD.xml");
DisplayMessage();
}
private void ValidateItemXMLButton_Click(object sender, EventArgs e)
{
ValidateXML("ItemWithDTD.xml");
DisplayMessage();
}
private void DisplayMessage()
{
MessageBox.Show("XML is " + (isValid ? "" : "NOT ") + "valid" + nl + nl + "Message:" + nl + messages.ToString() + nl + nl + "XML" + nl + xml.ToString());
isValid = true;
messages = new StringBuilder();
xml = new StringBuilder();
}
protected void ValidateXML(string xmlFileName)
{
try
{
XmlReaderSettings xmlSettings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Parse,
ValidationType = ValidationType.DTD
};
xmlSettings.ValidationEventHandler += new ValidationEventHandler(ValidationCallback);
XmlReader reader = XmlReader.Create(AppDomain.CurrentDomain.BaseDirectory + xmlFileName, xmlSettings);
while (reader.Read())
{
// nothing to do, just validating the xml packet
xml.AppendLine(reader.ReadOuterXml());
}
reader.Close();
}
catch (Exception ex)
{
messages.AppendLine("ERROR : " + ex.Message);
isValid = false;
}
}
private void ValidationCallback(object sender, ValidationEventArgs e)
{
isValid = false;
messages.AppendLine(e.Message);
}
В дополнение к приведенному выше коду, содержимое моих двух файлов XML (один действительный, а другой нет) и мой файл DTD показаны ниже...
ProductWithDTD.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Product SYSTEM "Product.dtd">
<Product ProductID="123">
<ProductName>Rugby jersey</ProductName>
</Product>
ItemWithDTD.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE Product SYSTEM "Product.dtd">
<Item ItemID="123">
<ItemName>Rugby jersey</ItemName>
</Item>
и, наконец, Product.dtd...
<!ELEMENT Product (ProductName)>
<!ATTLIST Product ProductID CDATA #REQUIRED>
<!ELEMENT ProductName (#PCDATA)>
Даже при обработке файла ProductWithDTD.xml я получаю ошибки проверки, указывающие, что элементы Product и ProductName не объявлены. Я ожидаю этого в файле ItemWithDTD.xml, но не в файле ProductWithDTD.xml.
У кого-нибудь есть идеи, почему это не удается? Все это готовится к проверке пакетов EDI cXML (которые также не работают), и они являются гораздо большими документами для проверки.
Благодарю.
0 ответов
Оказывается, проблема в том, что XmlReader фактически находит файл DTD для проверки, даже если это локальный файл.
Изменение определения XmlReaderSettings для включения стандартного XmlResolver устранило мою проблему.
XmlReaderSettings xmlSettings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Parse,
ValidationType = ValidationType.DTD,
XmlResolver = new XmlUrlResolver()
};