Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中使用XMLDOm查找节点值_Php_Xpath_Xmldom - Fatal编程技术网

在PHP中使用XMLDOm查找节点值

在PHP中使用XMLDOm查找节点值,php,xpath,xmldom,Php,Xpath,Xmldom,我需要使用XMLDom从XML中提取信息 下面是myroot.xml <?xml version='1.0' encoding='ISO-8859-1'?> <myroot xml:lang='en'> <delta> <history> <detail> <id>one</id> <degree>

我需要使用XMLDom从XML中提取信息

下面是myroot.xml

<?xml version='1.0' encoding='ISO-8859-1'?>
<myroot xml:lang='en'>
<delta>
    <history>
        <detail>
            <id>one</id>
            <degree>
                <dname>alpha</dname>
                <dates>
                    <StartDate>
                        <Year>1998</Year>
                    </StartDate>
                    <EndDate>
                        <Year>2002</Year>
                    </EndDate>
                </dates>
            </degree>
        </detail>
        <detail>
            <id>two</id>
            <degree>
                <dname>beta</dname>
                <dates>
                    <StartDate>
                        <Year>2006</Year>
                    </StartDate>
                    <EndDate>
                        <Year>2008</Year>
                    </EndDate>
                </dates>
            </degree>
        </detail>
    </history>
</delta>    

理想情况下,我需要使用xpath提取日期。我没办法把这个钉牢。感谢您的帮助。问题是循环时xpath的使用。

使用xpath直接转到yout
dates
标记,然后使用获取
StartDate
EndDate
(也可以使用
dates
标记,但xpath在需要时为您提供了更大的灵活性)。这将返回一个,但您知道(如果结构是常量),您只需要列表的第一个元素。因此:

// $xml ommited, saved in a variable for testing purposes
$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$items = $doc->getElementsByTagName("detail");
$subitemarray = array();
$icounter = 0;
foreach ($items as $item) {
    $query = "//dates"; //xpath of all occurrence of Year
    $entries = $xpath->query($query, $item);
    foreach ($entries as $entry) {
        $startDate = $entry->getElementsByTagName("StartDate")[0]->nodeValue;
        $endDate = $entry->getElementsByTagName("EndDate")[0]->nodeValue;
        $dates["startdate"] = $startDate; //extract StartDate
        $dates["enddate"] = $endDate;  //extract EndDate
    }
    $subitemarray[$icounter++] = $dates;
}
var_dump($subitemarray);

或者仅使用XPath:

$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$items = $doc->getElementsByTagName("detail");
$subitemarray = array();
$icounter = 0;
foreach ($items as $item) {
    $queryStart = "//dates/StartDate";
    $entriesStart = $xpath->query($queryStart, $item);
    $dates["startdate"] = $entriesStart[0]->nodeValue;

    $queryEnd = "//dates/EndDate";
    $entriesEnd = $xpath->query($queryEnd, $item);
    $dates["enddate"] = $entriesEnd[0]->nodeValue;
    $subitemarray[$icounter++] = $dates;
}
var_dump($subitemarray);
最后,只使用一个XPath查询:

$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$items = $doc->getElementsByTagName("detail");
$subitemarray = array();
$icounter = 0;
foreach ($items as $item) {
    $query = "//dates/*[contains(local-name(), 'Date')]
";
    $entries = $xpath->query($query, $item);
    $dates["startdate"] = $entries[0]->nodeValue;
    $dates["enddate"] = $entries[1]->nodeValue;
    $subitemarray[$icounter++] = $dates;
}
var_dump($subitemarray);


查询将只获取当前
detail
元素中包含单词“Date”的任何元素。同样,如果结构是常量,您可以假设第一个结果是
StartDate
,第二个结果是
EndDate

您的意思是什么@User4826347您的第二个选项对我来说很好,但对我来说不起作用。。。。不知道为什么它的表现不符合预期,你能详细说明一下吗?输出是什么?第一个或第三个示例对您有用吗?第二个选项没有输出。第三个例子是什么起作用。但我更喜欢直接xpath而不是使用contains。
$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$items = $doc->getElementsByTagName("detail");
$subitemarray = array();
$icounter = 0;
foreach ($items as $item) {
    $query = "//dates/*[contains(local-name(), 'Date')]
";
    $entries = $xpath->query($query, $item);
    $dates["startdate"] = $entries[0]->nodeValue;
    $dates["enddate"] = $entries[1]->nodeValue;
    $subitemarray[$icounter++] = $dates;
}
var_dump($subitemarray);