I created XSD using Visual StudioXML Tools. And I use following C# code to validate XML and facing this error.
Error
The elem
You are very close. In your XSD, simply replace,
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" />
with
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
schemaLocation=
"http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>
and your XSD will no longer have that error, and your XML will be valid against your XSD.
XSDs can be composed via xs:import and xs:include. In both cases, the location of the referenced XSD has to be specified with a required schemaLocation
attribute, which was missing in OP's original XSD. By adding xs:import/@schemaLocation
as shown above, the error is eliminated.
When you switched to use a local XSD, you made a mistake in your xs:import
:
Change
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212
file:///C:/Temp/xmldsig-core-schema.xsd"/>
to
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
schemaLocation="file:///C:/Temp/xmldsig-core-schema.xsd"/>
(You were following an example for @xsi:schemaLocation
in XML documents which has namespace-location pairs; xs:import/@schemaLocation
is different.)
So my question is how to fix it because in edit mode XML is valid 100%?
Perhaps this is the disconnect. Editing an XML file in Visual Studio does not automatically validate it against an XSD. You need to do that in code or via a validating XML editor such Oxygen XML Editor or XML Spy.
Also, your C# validation code may have issues. See Validating an XML against referenced XSD in C#
If you don't want to change anything to xsd or xml - do the following:
(optional) Download xsd from w3 site and save to local disk. W3 site is VERY slow because a lot of software worldwide constantly request those schemas. If you will use that xsd directly - you will often fail by timeout. Some validation tools already have such schemas cached locally, but not .NET validator.
Modify your validation method from UPDATE 2 the following way:
public static bool IsValidXml1(string xmlFilePath, string xsdFilePath, string namespaceName)
{
XDocument xdoc = null;
var settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Ignore;
try
{
using (XmlReader xr = XmlReader.Create(xmlFilePath, settings))
{
xdoc = XDocument.Load(xr);
var schemas = new XmlSchemaSet();
schemas.Add(namespaceName, xsdFilePath);
using (var fs = File.OpenRead(@"D:\Temp\xmldsig-core-schema.xsd"))
using (var reader = XmlReader.Create(fs, new XmlReaderSettings() {
DtdProcessing = DtdProcessing.Ignore // important
})) {
schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", reader);
}
xdoc.Validate(schemas, null);
return true;
}
}
catch (XmlSchemaValidationException ex)
{
// throw;
}
return false;
}
You have to add that schema using XmlReader
and not directly, because if you add directly (like in your update 2) - it will fail to parse DTD block, because when you add XmlSchema
to XmlSchemaSet
using url (or file path) - it will read that file using XmlReaderSettings
with DtdProcessing = DtdProcessing.Prohibit
. We need to change that to DtdProcessing.Ignore
or DtdProcessing.Parse
. After that your validation method will work fine for target xsd and xml file, without any changes (and will correctly fail in case xml does not match xsd).