[英]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.