سؤال

أنا أعمل مع بعض "مقتطفات XML" التي شكلت العناصر أسفل XML. لدي المخطط ولكن لا يمكنني التحقق من صحة هذه الملفات لأنها ليست مستندات XML كاملة. يتم لف هذه القصاصات عناصر الوالد الضرورية لتشكيل XML صالحة سارية عندما يتم استخدامها في أدوات أخرى لذلك ليس لدي خيار كبير في جعلها في XML صالحة أو في تغيير المخطط.

هل من الممكن التحقق من صحة عنصر، بدلا من المستند بأكمله؟ إذا لم يكن كذلك، ما هي الحلول التي يمكن اقتراحها؟

أنا أعمل في C # مع .NET 2.0 Framework.

هل كانت مفيدة؟

المحلول

كان لدي مشكلة مماثلة حيث يمكنني التحقق من صحة أجزاء من مستند 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 (الذي اخترته من XmLDocument بأكمله عن طريق .SelectsingLenode)، ومخطط XML الذي قمت بتحميله من مورد Embedded 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 كجذر. سيكون المخطط الناتج يبدو

<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 قالب فارغ. ثم استبدل العنصر المطلوب مع قصافي. من هناك، أعتقد أن طريقة التحقق من الصحة ستكون قابلة للحياة. ولكن لإنشاء هذا القالب يبدو ديناميكيا مهمة شاقة أخرى في حقها. لا يبدو أن هناك أي طريقة سهلة لإنشاء وثيقة "هيكل عظمي".

كان لي نفس المشكلة. حتى طلب هنا عن الحل. لقد وجدت الحل البديل.

المشكلة هي أنه يمكن التحقق من صحة العناصر الجذر فقط. هكذا ... قمت بتحرير المخطط في الذاكرة وإضافة العنصر / النوع للتحقق من الجذر

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 :) مع هذا التغيير البسيط إلى مخططك في الذاكرة، يمكنك التحقق من صحة الجزء مع نفس الرمز الذي تستخدمه للتحقق من صحة مستند كامل. فقط تأكد من أن العنصر الجذر في الجزء للتحقق من صحة الأساس يشمل مساحة الاسم. :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top