繁体   English   中英

验证xml节点,而不是整个文档

[英]Validating xml nodes, not the entire document

我正在使用一些xml'片段',它们在xml中形成元素。 我有架构,但我无法验证这些文件,因为它们不是完整的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模式,我从我的app中的嵌入式资源XSD加载。 可能发生的任何验证错误都被填充到“错误”字符串构建器中,然后我在最后读出,以查看是否记录了任何错误。

对我有用 - 你的里程可能会有所不同:-)

有一个XmlDocument.Validate方法,它将XmlNode作为参数,仅验证此节点。 那可能就是你要找的......

好的,这是另一种方法:

您可以使用XSLT转换将模式文件转换为以snippet元素为根的新模式。 说你的原始架构

<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为根的新架构。 结果模式看起来像

<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文档。

我有同样的问题。 甚至在这里要求解决方案。 我找到了一个解决方法。

问题是只能验证根元素。 所以...我编辑IN MEMORY方案并添加元素/类型以验证根

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文件:)通过对内存模式的这种简单更改,您可以使用用于验证完整文档的相同代码验证该片段。 只需确保要验证的片段的根元素包含命名空间。 :)

您可以使用特殊的命名空间别名来标记要验证的元素,然后只为该命名空间别名添加模式,而不为其他人添加模式。 这样,只有具有特殊名称空间前缀的元素才会被验证。

似乎不可能做我渴望做的事情。 我目前的工作是创建一个空白模板xml文档。 然后用我的代码片段替换所需的元素。 从那里,我相信Validate方法将是可行的。 但是动态创建这个模板似乎本身就是另一项艰巨的任务。 似乎没有任何简单的方法来创建“骨架”文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM