XMLノードの検証、全体ではなく、文書
-
23-08-2019 - |
質問
私は、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);
}
基本的に、私はそれは私が自分のアプリケーション内に埋め込まれたリソースXSDからロードする(Iは.SelectSingleNodeにより全体のXmlDocumentから選択)のXmlNode、およびXMLスキーマを渡します。発生する可能性の検証エラーは、私はその後、何らかのエラーが記録されない、またはあったかどうかを確認するために、最後に読み出した「エラー」の文字列ビルダ、に詰めされています。
私のための作品集 - あなたの走行距離は異なる場合があります: - )
他のヒント
引数ANのみこのノードを検証するようXmlDocument.Validate
を取るXmlNode
の方法があります。それはあなたが探しているものかもしれ...
[OK]を、ここでは別のアプローチです:
rootとしてスニペットの要素を持つ新しいスキーマに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
た新しいスキーマを作成します。結果のスキーマは次のようになります。
<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ファイルを追加してはいけません:)あなたのメモリ内のスキーマにこの単純な変更により、あなたは完全なドキュメントを検証するために使用するのと同じコードを持つフラグメントを検証することができます。ただ、検証するフラグメントのルート要素が名前空間が含まれていることを確認してください。 :)