XML Signature element is not declared
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.
Explanation
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.
Update #1:
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.)
Update #2:
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).