XmlDocument.Validate不支持的属性或元素
问题描述:
如何获取ValidationEvents如果theire是xml中未定义在xsd中的属性或元素。XmlDocument.Validate不支持的属性或元素
的xsd:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema id="VoiceXmlTSPro"
targetNamespace="http://tempuri.org/VoiceXmlTSPro.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/VoiceXmlTSPro.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Elements-->
<xsd:element name="vxml">
<xsd:complexType>
<xsd:attribute ref="base"/>
<xsd:attribute ref="lang"/>
</xsd:complexType>
</xsd:element>
<!-- End Elements-->
<!-- Attributes-->
<xsd:attribute name="base" type="xsd:anyURI">
</xsd:attribute>
<xsd:attribute name="lang" type="xsd:string">
</xsd:attribute>
<!-- End Attributes-->
</xsd:schema>
XML:
<?xml version="1.0" encoding="utf-8" ?>
<vxml application="notsupported" lang="en-US" base="http://www.zebra.com">
<unknow></unknow>
</vxml>
我要为应用性质和对不明ellement警告。 但是这段代码并没有拖延任何事件。
public override void Validate(string source)
{
ValidationResults.Clear();
XmlSchemaFactory xmlSchemaFactory = new XmlSchemaFactory();
XmlReaderSettings vxmlTestSettings = new XmlReaderSettings();
vxmlTestSettings.ValidationType = ValidationType.Schema;
vxmlTestSettings.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints| XmlSchemaValidationFlags.ReportValidationWarnings ;
try
{
XmlSchema xsdSchema = xmlSchemaFactory.Create(Resource.VoiceXmlTSPro);
if (xmlSchemaFactory.HasErrors())
{
// if the schema is invalid the read wil not read
return;
}
vxmlTestSettings.Schemas.Add(xsdSchema);
ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationHandler);
using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(source)))
using (XmlReader xmlReader = XmlReader.Create(stream, vxmlTestSettings))
{
XmlDocument document = new XmlDocument();
document.Load(xmlReader);
document.Validate(eventHandler);
}
}
catch (Exception ex)
{
...
}
}
答
如果你需要做的就是验证XML标记的字符串中的一个模式,然后解析与XmlReader
串在适当应该做一个StringReader
,就没有必要使用XmlDocument
及其Validate
方法。
下面是一个例子,对于第一样品仅输出警告作为输入文档没有命名空间声明,为对第二文档大约有未申报元件错误和属性:
static void Main(string[] args)
{
string[] xmls = { @"<vxml application=""notsupported"" lang=""en-US"" base=""http://www.zebra.com"">
<unknow></unknow>
</vxml>",
@"<vxml application=""notsupported"" lang=""en-US"" base=""http://www.zebra.com"" xmlns=""http://example.com/ns1"">
<unknow></unknow>
</vxml>"
};
foreach (string xml in xmls)
{
Console.WriteLine("Validating");
Validate(xml, "../../schema1.xml");
Console.WriteLine();
}
}
static void Validate(string xmlMarkup, string schemaUri)
{
XmlReaderSettings xrs = new XmlReaderSettings();
xrs.Schemas.Add(null, schemaUri);
xrs.ValidationType = ValidationType.Schema;
xrs.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
xrs.ValidationEventHandler += (obj, valArgs) =>
{
Console.WriteLine("{0}: {1}", valArgs.Severity, valArgs.Message);
};
using (StringReader sr = new StringReader(xmlMarkup))
{
using (XmlReader xr = XmlReader.Create(sr, xrs))
{
while (xr.Read()) { }
}
}
}
架构是
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema id="VoiceXmlTSPro"
targetNamespace="http://example.com/ns1"
elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Elements-->
<xsd:element name="vxml">
<xsd:complexType>
<xsd:attribute name="base" type="xsd:anyURI"/>
<xsd:attribute name="lang" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<!-- End Elements-->
</xsd:schema>
输出
Validating
Warning: Could not find schema information for the element 'vxml'.
Warning: Could not find schema information for the attribute 'application'.
Warning: Could not find schema information for the attribute 'lang'.
Warning: Could not find schema information for the attribute 'base'.
Warning: Could not find schema information for the element 'unknow'.
Validating
Error: The 'application' attribute is not declared.
Error: The element cannot contain white space. Content model is empty.
Error: The element 'http://example.com/ns1:vxml' cannot contain child element 'http://example.com/ns1:unknow' because the parent element's content model is empty.
那么,什么是你的目标恰好,试图使用XML实例文档验证字符串是否符合.NET框架中设置的特定模式或模式?或者使用'Validate'方法?如果模式具有'targetNamespace =“http://tempuri.org/VoiceXmlTSPro.xsd”',为什么你的实例不声明那个名字空间?使用您当前的实例文档,您只会收到有关根元素没有模式的警告。 –