我有一个关于使用XmlDocument类进行XML验证的问题,尤其是它的.Validate()
方法。场景如下:
我有一个看起来像这样的XML:
<root>
<Message id="1234">
<Content1>
<randomTag1>data</randomTag1>
<randomTag2>data</randomTag2>
</Content>
</Message>
<root>
以及以下两个.xsd模式
1:
<xs:schema id="root" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="rType"/>
<xs:complexType name="ThreeDSecure">
<xs:sequence>
<xs:element name="Message" type="Message"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Message">
<xs:choice maxOccurs="1">
<xs:element name="Content1"/>
<xs:element name="Content2"/>
</xs:choice>
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
2:
<xs:schema id="Content1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Content1" type="c1Type"/>
<xs:complexType name="c1Type">
<xs:sequence>
<xs:element name="randomTag1"/>
<xs:element name="randomTag2"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
目标是能够加载XmlDocument
并将两个XmlSchemaSet
添加到其中,然后能够使用第一个.xsd验证整个文档,然后验证没有错误,可以使用第二个.xsd
<Content1>
节点
我正在使用的代码是这样的:
public bool Parse(string xmlString)
{
var doc = new XmlDocument();
try { doc.LoadXml(xmlString); }
catch (Exception ex)
{
return false;
}
var errors = new List<string>();
doc.Schemas.Add(/*load the first schema*/);
doc.Validate((o, e) =>
{
if (e.Severity == XmlSeverityType.Error)
errors.Add(e.Message);
});
if(errors.Count > 0)
{
return false;
}
var msgNode = doc.SelectSingleNode("//Message");
var realMsg = msgNode.FirstChild;
//we do this because we do not know if this node is "Content1" or "Content2" because for "Content2" there is a different .xsd schema
doc.Schemas.Add(/*load the second schema using the realMsg.Name*/);
errors.Clear();
doc.Validate((o,e) =>
{
if(e.Severity == XmlSeverityType.Error)
errors.Add(e.Message);
});
if (errors.Count > 0)
{
return false;
}
return true;
}
代码运行良好,但是当我有意为<Content1>
标签发送错误的XML格式时,第二次验证不会产生任何错误。
这一定是我做错了,但是我找不到它是什么。 或者,也许我会以另一种(我不知道的)方法来解决问题?
-------编辑--------
我尝试了相同的xsd模式,但是我将它们加载到了不同的XmlDocument
中,并且效果很好:
public bool Parse(string xmlString)
{
var doc = new XmlDocument();
try { doc.LoadXml(xmlString); }
catch (Exception ex)
{
return false;
}
var errors = new List<string>();
doc.Schemas.Add(/*load the first schema*/);
doc.Validate((o, e) =>
{
if (e.Severity == XmlSeverityType.Error)
errors.Add(e.Message);
});
if(errors.Count > 0)
{
return false;
}
var msgNode = doc.SelectSingleNode("//Message");
var realMsg = msgNode.FirstChild;
var realDoc = new XmlDocument();
realDoc.LoadXml(realMsg.OuterXml);
//we do this because we do not know if this node is "Content1" or "Content2" because for "Content2" there is a different .xsd schema
realDoc.Schemas.Add(/*load the second schema using the realMsg.Name*/);
errors.Clear();
realDoc.Validate((o,e) =>
{
if(e.Severity == XmlSeverityType.Error)
errors.Add(e.Message);
});
if (errors.Count > 0)
{
return false;
}
return true;
}
有什么办法可以避免创建新的XmlDocument
?
关于, 朱利安