سؤال

وأنا أعمل على اختبار التطبيق الآلي، وأنا حاليا في عملية كتابة وظيفة أن يقارن القيم بين ملفين XML التي يجب أن تكون متطابقة، ولكن قد لا يكون. وفيما يلي عينة من XML أحاول أن العملية:

<?xml version="1.0" encoding="utf-8"?>
<report xmlns="http://www.**.com/**">
  <subreport name="RBDReport">
    <record rowNumber="1">
      <field name="Time">
        <value>0</value>
      </field>
      <field name="Reliability">
        <value>1.000000</value>
      </field>
      <field name="Unreliability">
        <value>0.000000</value>
      </field>
      <field name="Availability">
        <value> </value>
      </field>
      <field name="Unavailability">
        <value> </value>
      </field>
      <field name="Failure Rate">
        <value>N/A</value>
      </field>
      <field name="Number of Failures">
        <value> </value>
      </field>
      <field name="Total Downtime">
        <value> </value>
      </field>
    </record>

و(ملاحظة قد يكون هناك عناصر <subreport> متعددة وضمن تلك، عناصر <record> متعددة.)

ما أود أن استخراج العلامات <value> وثيقتين ثم قارن قيمهم. هذا الجزء أعرف كيفية القيام به. المشكلة تكمن في استخراج نفسها.

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

وهذا المجمع، CSimpleXMLParser، تحميل مستند XML ويحدد "سجلها كبار" لعنصر ثيقة من وثائق وثيقة XML. (CRecord كونه فئة مجردة مع CXMLRecord واحدة من الفئات الفرعية، والذي يتيح الوصول إلى السجلات التابعة منفردة أو من قبل مجموعة، والسماح أيضا الوصول إلى "قيمة" للسجل (قيم العناصر التابعة أو سمات، في حالة CXMLRecord .) A CXMLRecord يحتوي على MSXML :: MSXMLDOMNodePtr ومؤشر إلى مثيل CSimpleXMLParser). والمجمع يحتوي أيضا على وظائف لفائدة الأطفال العائدين، والذي يستخدم CXMLRecord للعودة السجلات التابعة لها.

في قانون بلدي، وأنا لا ما يلي (في محاولة للعودة كافة العقد <subreport> فقط لمعرفة ما اذا كان يعمل):

CSimpleXMLParser parserReportData;
parserReportData.OpenXMLDocument(strPathToXML);
bool bGetChildrenSuccess = parserReportData.GetFirstRecord()->GetChildRecords(listpChildren, _T("subreport"));

وهذا يعود دائما كاذبة. لحوم تنفيذ CXMLRecord :: GetChildRecords () هو في الأساس

MSXML2::IXMLDOMNodeListPtr pListChildren = m_pParser->SelectNodes(strPath, m_pXMLNode);

if (pListChildren->Getlength() == 0)
{
    return false;
}

for (long l = 0; l < pListChildren->Getlength(); ++l)
{
    listRecords.push_back(new CXMLRecord(pListChildren->Getitem(l), m_pParser));
}

return true;

وCSimpleXMLParser :: SelectNodes () هو:

MSXML2::IXMLDOMNodeListPtr CSimpleXMLParser::SelectNodes(LPCTSTR strXPathFilter, MSXML2::IXMLDOMNodePtr pXMLNode)
{
    return pXMLNode->selectNodes(_bstr_t(strXPathFilter));
}

عند تشغيل، وبالتأكيد يجري تعيين سجل أعلى لعنصر <report> بشكل صحيح. أستطيع كل أنواع الأشياء معها، مثل الحصول على العقد التابعة لها (من خلال واجهة MSXML، وليس من خلال المجمع بلدي) أو اسمها، وما إلى ذلك وأنا أعلم أن بلدي المجمع <م> يمكن العمل، لأنني أستخدم في مكان آخر في التطبيق لتحليل ملف تكوين XML، والذي يعمل لا تشوبه شائبة.

واعتقدت ربما كنت تفعل شيئا خاطئ مع التعبير استعلام XPath، ولكن كل التقليب كنت أفكر فيه لا يعطي الفرح. وMSXML::IXMLDOMNodeListPtr إرجاعها بواسطة IXMLDOMNodePtr::SelectNodes() دائما من طول 0 عندما أحاول التعامل مع هذا الملف XML.

وهذا يقود لي مجنون.

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

المحلول

واعتدت على القيام بذلك مع الكائنات XmlDocument. NET، ولكن أعتقد أن التأثير هو نفسه هنا:

إذا وتتضمن وثيقة XML مساحة اسم - حتى واحد اسمه - ثم استعلام XPath له لاستخدام واحد كذلك. لذلك، سيكون لديك لإضافة مساحة إلى XMLDoument التي قد تعطي كذلك اسما في التعليمات البرمجية، وتشمل البادئة في الاستعلام XPATH (لا يهم أن البادئات مختلفة بين وثيقة XML و وكسباث، طالما مساحات فرز بها)

وSO، في حين كنت تستخدم كسباث مثل /report/subreport/record/field/value، تحتاج فعلا إلى المجموعة الأولى مساحة الاسم المستند:

  pXMLDoc->setProperty(_bstr_t("SelectionNamespaces"),
                       _bstr_t("xmlns:r="http://www.**.com/**"));

وثم selectNodes() باستخدام /r:report/r:subreport/r:record/r:field/r:value

نصائح أخرى

وأنا لا أرى أي إشارة إلى مساحة الاسم عندما كنت اختيار العقد. أتوقع أن تكون هذه هي المشكلة الأساسية.

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