Is there something I need to configure in the XmlReaderSettings to encourage .net (4.8, 6, 7) to handle some cXML without throwing the following exception:
Unhandled exception. System.Xml.Schema.XmlSchemaException: The parameter entity replacement text must nest properly within markup declarations.
Sample cXML input
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.041/cXML.dtd">
<cXML payloadID="donkeys@example.com" timestamp="2023-02-13T01:01:01Z">
<Header>
</Header>
<Request deploymentMode="production">
</Request>
</cXML>
Sample Application
using System.Xml;
using System.Xml.Linq;
namespace Donkeys
{
internal class Program
{
static void Main()
{
XmlReaderSettings settings = new()
{
XmlResolver = new XmlUrlResolver(),
DtdProcessing = DtdProcessing.Parse,
ValidationType = ValidationType.DTD,
};
FileStream fs = File.OpenRead("test.xml"); // sample cXML from question
XmlReader reader = XmlReader.Create(fs, settings);
XDocument.Load(reader); // this blows up
}
}
}
I'm looking to use the XmlUrlResolver
to cache the DTDs but without ignoring the validation I get the error above but i'm not really sure why?
So far I've tried different validation flags but they don't validate at all unless I use ValidationType.DTD
which goes pop.
The actual resolver seems to work fine; if I subclass it, it is returning the DTD (as a MemoryStream
) as expected.
I can add an event handler to ignore the issue but this feels lamer than I'd like.
using System.Xml;
using System.Xml.Linq;
namespace Donkeys
{
internal class Program
{
static void Main()
{
XmlReaderSettings settings = new()
{
XmlResolver = new XmlUrlResolver(),
DtdProcessing = DtdProcessing.Parse,
ValidationType = ValidationType.DTD,
IgnoreComments = true
};
settings.ValidationEventHandler += Settings_ValidationEventHandler;
FileStream fs = File.OpenRead("test.xml");
XmlReader reader = XmlReader.Create(fs, settings);
XDocument dogs = XDocument.Load(reader);
}
private static void Settings_ValidationEventHandler(object? sender, System.Xml.Schema.ValidationEventArgs e)
{
// this seems fragile
if (e.Message.ToLower() == "The parameter entity replacement text must nest properly within markup declarations.".ToLower()) // and this would be a const
return;
throw e.Exception;
}
}
}