Xml验证不是我触摸的东西,除非我不得不这样做,所以我可能会丢失一些愚蠢的东西,到目前为止,我在Google上搜索任何帮助都没有成功。我的问题是我有一个限制类型,它只能是字母或空格。具有前导换行符的元素未通过验证,但尾随换行符未通过。如何让尾随换行失败?
我创建了一个精简测试用例如下:
验证码:
public List<XsdValidationError> ValidateXmlAgainstXsd(String xml, String xsdFilePath, Boolean processSchemaLocation = false)
{
var ret = new List<XsdValidationError>();
var xss = new XmlSchemaSet();
var xmlUrlResolver = new XmlUrlResolver();
xmlUrlResolver.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
xss.XmlResolver = xmlUrlResolver;
var xsdXElement = XElement.Parse(File.ReadAllText(xsdFilePath));
var targetNamespaceAttribute = xsdXElement.Attribute("targetNamespace");
xss.Add(targetNamespaceAttribute != null ? targetNamespaceAttribute.Value : "", xsdFilePath);
var settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas = xss;
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema;
if (processSchemaLocation)
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationEventHandler += (sender, e) =>
{
var xve = new XsdValidationError { Message = e.Message, LineNumber = e.Exception.LineNumber, LinePosition = e.Exception.LinePosition };
ret.Add(xve);
};
using (var sr = new StringReader(xml))
{
var xr = XmlReader.Create(sr, settings);
while (xr.Read());
return ret;
}
}
public class XsdValidationError
{
public String Message { get; set; }
public int LineNumber { get; set; }
public int LinePosition { get; set; }
public override string ToString()
{
return String.Format("Line {0:n0}, Position {1:n0}: {2}", this.LineNumber, this.LinePosition, this.Message);
}
}
输入XML和XSD:
<People>
<Person>Hello Person One
</Person>
<Person>Hello Person Two</Person>
<Person>
Hello Person Three</Person>
</People>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="People">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" maxOccurs="unbounded">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z ]+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
在XML人中,一个人不会失败,第二个人应该通过,第三个人应该失败。我需要一个人也失败。
我无法更改输入XML或XSD。 Visual Studio正确验证该文件。有什么想法吗?
答案 0 :(得分:1)
我认为这是微软XSD解析器的一个怪癖/错误。 xs:string类型的定义是: -
<xsd:simpleType name="string" id="string">
<xsd:restriction base="xsd:anySimpleType">
<xsd:whiteSpace value="preserve"/>
</xsd:restriction>
</xsd:simpleType>
由于空白面被设置为“保留”,它应该包含元素,空格和所有内容中的所有内容。
然而,你已经注意到它忽略了尾随的空格。除了在代码中手动应用验证规则之外,似乎除此之外没有太多可以做的事情。
它很容易在Xerces中按预期验证(前导空格和尾随空格都出错)。
答案 1 :(得分:0)
我发现如果我切换到使用XmlDocument来加载xml,那么它会正确验证,但是我丢失了行号信息。我不确定幕后发生了什么,但是改为这样就可以在我的情况下正确验证。
var xd = new XmlDocument();
xd.LoadXml(xml);
var xr = XmlReader.Create(new XmlNodeReader(xd), settings);