Crawler没有在Symfony 2.3上正确选择XML的节点

时间:2014-07-22 12:07:53

标签: xml symfony xpath symfony-2.3 web-crawler

我正在申请进口QTI,我遇到了以下问题:

我得到一个包含测试(assessmentTest)的XML文件,该文件又包含对问题的引用(名为assessmentItems)。 XML文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<assessmentTest xmlns="http://www.imsglobal.org/xsd/imsqti_v2p1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqti_v2p1 imsqti_v2p1.xsd" identifier="AT-196b0997-3ec6-4b4e-8b22-c3d563f71291" title="Quiz example">
  <outcomeDeclaration identifier="SCORE" cardinality="single" baseType="float" />
  <testPart identifier="TP-9ee1d731-c360-4989-bb50-c8bae65d2f8a-2" navigationMode="nonlinear" submissionMode="simultaneous">
    <assessmentSection identifier="AS-b602c887-a711-417b-bfad-6fe005fc085f-3" required="false" fixed="false" title="" visible="true" keepTogether="true">
      <selection select="2" withReplacement="false" />
      <ordering shuffle="true" />
      <assessmentItemRef identifier="AIR-5d0d9526-80ba-4956-8017-0fe6b9ef45d7-9" href="test/AI-15149c8b-8856-4117-9de3-e073552e668d-4.xml" />
      <assessmentItemRef identifier="AIR-c112b4d4-6003-4d17-a2c5-55a2d3d6388c-24" href="test/AI-b6b27861-3d27-4876-afb3-c33daf2d7fad-19.xml" />
    </assessmentSection>
  </testPart>
  <outcomeProcessing>
    <setOutcomeValue identifier="SCORE">
      <sum>
        <testVariables variableIdentifier="SCORE" />
      </sum>
    </setOutcomeValue>
  </outcomeProcessing>
  <testFeedback access="atEnd" showHide="hide" outcomeIdentifier="outcomeIdentifier" identifier="outcomeValue" title="Detailed Breakdown">
    <p>The test is now complete. The following table shows a breakdown of your scores:</p>
    <table>
      <tbody>
        <tr>
          <td>The total score:</td>
          <td>
            <printedVariable identifier="SCORE" />
          </td>
        </tr>
      </tbody>
    </table>
  </testFeedback>
</assessmentTest>

我使用以下代码来获取引用:

 if (!empty($assessmentsTest)) {
     foreach ($assessmentsTest as $assessmentTest) {
         $crawler = new Crawler (file_get_contents(sys_get_temp_dir()."/qti-pack/".$assessmentTest));

         $items = $crawler->filterXPath('/assessmentTest/testPart/assessmentSection//assessmentItemRef');

         for ($i=0; $i < $items->count(); $i++) { 
             $assessmentsItem [] = $items->eq($i)->attr('href');
         }
     }
 }

但这并不好用。如果我忽略'for'并使用更直接的代码:

echo $items->eq(0)->attr('href');

返回以下错误:“当前节点列表为空。”

我尝试了xPath的其他变体但得到了相同的错误。

P.D。:对不起我的英语不好,这不是我的母语。

2 个答案:

答案 0 :(得分:2)

我不使用Symfony,但这是处理XML的常见问题。您的XML具有在根级别定义的默认命名空间(xmlns="..."),因此在上述默认命名空间中将考虑所有没有不同默认命名空间声明且没有前缀的节点。

根据documentation,从版本2.4开始,默认命名空间自动注册default前缀,因此您可以尝试使用此XPath:

/default:assessmentTest/default:testPart/default:assessmentSection/default:assessmentItemRef

更新:

在Symfony2上找到关于手动名称空间前缀注册的互联网文档有点困难,你能尝试这样的事情(从here得到了想法):

$crawler->registerNamespace('default', 'http://www.imsglobal.org/xsd/imsqti_v2p1')
$items = $crawler->filterXPath('/default:assessmentTest/default:testPart/default:assessmentSection/default:assessmentItemRef');

答案 1 :(得分:0)

我回答自己:

if (!empty($assessmentsTest)) {
    foreach ($assessmentsTest as $assessmentTest) {
        $crawler = new Crawler();
        $crawler->addXmlContent(file_get_contents(sys_get_temp_dir()."/qti-pack/".$assessmentTest));

        $items = $crawler->filterXPath('//assessmentItemRef');

        for ($i=0; $i < $items->count(); $i++) { 
            $assessmentsItem [] = $items->eq($i)->attr('href');
        }
    }
}

结束是一个简单的解决方案。