我正在使用一些在 xml 中形成元素的 xml 'snippets'。我有架构,但我无法验证这些文件,因为它们不是完整的 xml 文档。这些片段包含必要的父元素以在其他工具中使用它们时形成有效的 xml,因此我没有太多选择将它们变成有效的 xml 或更改架构。
是否可以验证一个元素,而不是整个文档?如果没有,可以建议哪些解决方法?
我正在使用 .NET 2.0 框架使用 C#。
我正在使用一些在 xml 中形成元素的 xml 'snippets'。我有架构,但我无法验证这些文件,因为它们不是完整的 xml 文档。这些片段包含必要的父元素以在其他工具中使用它们时形成有效的 xml,因此我没有太多选择将它们变成有效的 xml 或更改架构。
是否可以验证一个元素,而不是整个文档?如果没有,可以建议哪些解决方法?
我正在使用 .NET 2.0 框架使用 C#。
我有一个类似的问题,我只能验证我的 XML 文档的一部分。我在这里想出了这个方法:
private void ValidateSubnode(XmlNode node, XmlSchema schema)
{
XmlTextReader reader = new XmlTextReader(node.OuterXml, XmlNodeType.Element, null);
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.Schemas.Add(schema);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);
using (XmlReader validationReader = XmlReader.Create(reader, settings))
{
while (validationReader.Read())
{
}
}
}
private void XSDValidationEventHandler(object sender, ValidationEventArgs args)
{
errors.AppendFormat("XSD - Severity {0} - {1}",
args.Severity.ToString(), args.Message);
}
基本上,我将一个 XmlNode(我通过 .SelectSingleNode 从整个 XmlDocument 中选择)和一个 XML 模式传递给它,我从我的应用程序内的嵌入式资源 XSD 加载它。任何可能发生的验证错误都被填充到“错误”字符串构建器中,然后我在最后读出它,以查看是否记录了任何错误。
对我有用-您的里程可能会有所不同:-)
有一种XmlDocument.Validate
方法接受一个XmlNode
作为参数,并且只验证这个节点。这可能是你正在寻找的...
好的,这是另一种方法:
您可以使用 XSLT 转换将您的模式文件转换为以您的片段元素为根的新模式。假设您的原始架构是
<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence>
<xs:element name="NestedElement">
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
NestedElement
您有要验证的类型片段:
<NestedElement Name1="Name1" />
然后您可以使用 XSLT 模板,例如
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="xs:element[@name='NestedElement']"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:schema id="MySchema">
<xsl:copy-of select="."/>
</xs:schema>
</xsl:template>
</xsl:stylesheet>
创建一个具有NestedElement
root 权限的新模式。生成的架构看起来像
<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="NestedElement">
<xs:complexType>
<xs:attribute name="Name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
然后,您可以使用类似的代码针对这个新模式验证片段文档
XmlSchema schema;
using (MemoryStream stream = new MemoryStream())
using (FileStream fs = new FileStream("MySchema.xsd", FileMode.Open))
using(XmlReader reader = XmlReader.Create(fs)) {
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("SchemaTransform.xslt");
transform.Transform(reader, null, stream);
stream.Seek(0, SeekOrigin.Begin);
schema = XmlSchema.Read(stream, null);
}
XmlDocument doc = new XmlDocument();
doc.Schemas.Add(schema);
doc.Load("rootelement.xml");
doc.Validate(ValidationHandler);
MySchema.xsd
是原始模式,SchemaTransform.xslt
是转换(如上所示),rootelement.xml
是包含单个片段节点的 XML 文档。
您可以使用特殊的命名空间别名来指定要验证的元素,然后仅为该命名空间别名添加架构,而不为其他命名空间别名添加架构。这样,只有那些带有特殊命名空间前缀的元素才会被验证。
似乎不可能做我渴望做的事。我目前的工作是创建一个空白模板 xml 文档。然后用我的代码段替换所需的元素。从那里开始,我相信 Validate 方法将是可行的。但是动态创建这个模板本身似乎是另一项艰巨的任务。似乎没有任何简单的方法可以创建“骨架”文档。
我有同样的问题。甚至在这里寻求解决方案。我找到了一种解决方法。
问题是只能验证根元素。所以...我在内存中编辑方案并将要验证的元素/类型添加到根
public static void AddElementToSchema(XmlSchema xmlSchema, string elementName, string elementType, string xmlNamespace)
{
XmlSchemaElement testNode = new XmlSchemaElement();
testNode.Name = elementName;
testNode.Namespaces.Add("", xmlNamespace);
testNode.SchemaTypeName = new XmlQualifiedName(elementType, xmlNamespace);
xmlSchema.Items.Add(testNode);
xmlSchema.Compile(XMLValidationEventHandler);
}
只需几行,您就不能修改或添加任何 XSD 文件 :) 通过对内存模式的这种简单更改,您可以使用用于验证完整文档的相同代码来验证片段。只需确保要验证的片段的根元素包含命名空间即可。:)