如何使用PHP根据另一个节点值在xml中获取特定节点?

时间:2016-09-23 18:39:47

标签: php xml simplexml

我正在尝试使用XML这样的示例:

<?xml version="1.0"?>
<quizReport version="1" xsi:schemaLocation="http://www.ispringsolutions.com/ispring/quizbuilder/quizresults quizReport.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ispringsolutions.com/ispring/quizbuilder/quizresults">
<quizSettings timeLimit="0" maxNormalizedScore="100" maxScore="20" quizType="graded">

<passingPercent>0.6</passingPercent>
</quizSettings>
<summary time="4" percent="0.5" score="10">
<variables>
  <variable title="Nom" value="test1411" name="USER_NAME"/>

  <variable title="Courriel" value="" name="USER_EMAIL"/>
</variables>
</summary>


<questions>
<trueFalseQuestion usedAttempts="1" awardedPoints="10" maxAttempts="1" maxPoints="10" status="correct" id="{11AD6662-ACF3-4C2B-A3E6-04311C0DD8DB}">
<direction>Le mot de passe de votre compte iNews est indépendant de votre mot de passe radiocanadien géré par ActiveDirectory. </direction>
<answers userAnswerIndex="0" correctAnswerIndex="0">
<answer>Vrai </answer>
<answer>Faux </answer>
</answers>
</trueFalseQuestion>

<trueFalseQuestion usedAttempts="1" awardedPoints="0" maxAttempts="1" maxPoints="10" status="incorrect" id="{F13CF7F1-C830-41AF-A54C-CE78EE383611}">
<direction>Le protocole FTP permet de reprendre un transfert de fichier qui a été arrêté, sans recommencer le transfert depuis le début. </direction>
<answers userAnswerIndex="1" correctAnswerIndex="0">
<answer>Vrai </answer>
<answer>Faux </answer>
</answers> 
</trueFalseQuestion>
</questions> 
</quizReport>

每个问题都有一个ID属性,例如 {11AD6662-ACF3-4C2B-A3E6-04311C0DD8DB} 的。 问题的状态以文本形式返回(即正确不正确)。

我的目标是提取每个问题状态并放入一个数据库,其中列标有相同的问题ID(我很熟悉MySQL INSERT)。

我尝试了很多解决方案(xPath,foreach ......),但我无法使用任何代码。我所有的努力都是用SimpleXMLElement完成的。​​

因此,最后,我会将值正确错误插入到标有问题ID的列下的数据库中(例如 {11AD6662-ACF3 -4C2B-A3E6-04311C0DD8DB} )用于XML的每个问题(最多可包含100个问题)。因此需要在XML中进行某种循环。

我必须指出标签名称 truFalseQuestion 可能会根据问题的类型而改变(例如,另一个问题可能是multipleChoiceQuestion)。我制作了这个简单的XML来帮助我逐步理解。

2 个答案:

答案 0 :(得分:0)

您可以使用PHP SimpleXML library来处理解析xml的问题。 e.g:

//presuming that xml data is stored in $xmlContents
$xmlData = new SimpleXMLElement($xmlContents);
$keys = get_object_vars($xmlData);
$aValues = array();
foreach($keys as $key=>$property) {
    if (stripos($key,'questions')!== false) {       
        foreach($property as $questionType=>$question) {
            $aValues[] = "('".(string)$question['id']."','".(string)$question['status']."')";
        }
    }
}
if (count($aValues)) {
    //presumed table and columns - modify per your names - this is a sample SQL statement - if you are using a different database variant, modify accordingly
    $query = 'INSERT INTO questionStatus (questionId,status) VALUES ' .     implode(',',$aValues);
    print($query);
    //@TODO: run insert statement with your database layer code
}

使用您的数据输出:

INSERT INTO questionStatus (questionId,status) VALUES ('{11AD6662-ACF3-4C2B-A3E6-04311C0DD8DB}','correct'),('{F13CF7F1-C830-41AF-A54C-CE78EE383611}','incorrect')

答案 1 :(得分:0)

您可以遍历问题元素的所有子节点。

可以使用getName()函数找到每个子节点的标记名。

这是一些示例代码。我希望,它可以帮助你获得一个想法。

<?php
//if your XML is stored in a file named "test.xml", you can load it from there.
//Otherwise try simplexml_load_string($xmlstring)
$file=simplexml_load_file("test.xml");

//get the questions
$questions=$file->questions->children();
foreach($questions as $question) {

    //as a sample there is some data printed for each question.
    print "QuestionType: ". $question->getName()."\n";
    print "QuestionID: ". $question->attributes()->id."\n";
    print "Direction: ".(string) $question->direction."\n";
    print "\n";
    print "Answers: \n";
    foreach($question->answers->answer as $answer){
        print (string)$answer."\n";
    }

    print "\n\n";
}

[编辑]

它打印的内容如下:

QuestionType: trueFalseQuestion
QuestionID: {11AD6662-ACF3-4C2B-A3E6-04311C0DD8DB}
Direction: Le mot de passe de votre compte iNews est indépendant de votre mot de passe radiocanadien géré par ActiveDirectory. 

Answers: 
Vrai 
Faux 


QuestionType: trueFalseQuestion
QuestionID: {F13CF7F1-C830-41AF-A54C-CE78EE383611}
Direction: Le protocole FTP permet de reprendre un transfert de fichier qui a été arrêté, sans recommencer le transfert depuis le début. 

Answers: 
Vrai 
Faux 

[/编辑]

Edit2:将id添加到示例代码和示例输出