Php 如何使用XMLReader解析XML元素/子元素的多个同名属性
我使用XMLReader和PHP处理一个中等大小的XML文件(6mb),基本上分解属性数据并将其插入到我自己的数据库中。问题是,每个元素都有数量可变的子元素,这些子元素的属性名称相同 以下是一个示例(这是govtrack.us提供的有关政府的公开数据): 为了得到“id”,它给了我两次,在元素中有多少子元素,就用多少换行符分开(我认为上面的注释说明了这一点,但我不确定该怎么办) 2) 如何按顺序访问每个子元素的属性?这:Php 如何使用XMLReader解析XML元素/子元素的多个同名属性,php,xml,xmlreader,Php,Xml,Xmlreader,我使用XMLReader和PHP处理一个中等大小的XML文件(6mb),基本上分解属性数据并将其插入到我自己的数据库中。问题是,每个元素都有数量可变的子元素,这些子元素的属性名称相同 以下是一个示例(这是govtrack.us提供的有关政府的公开数据): 为了得到“id”,它给了我两次,在元素中有多少子元素,就用多少换行符分开(我认为上面的注释说明了这一点,但我不确定该怎么办) 2) 如何按顺序访问每个子元素的属性?这: $p->getAttribute('startdate') 提供由
$p->getAttribute('startdate')
提供由多个换行符分隔的每个“startdate”值。我只需要获取元素的id,然后循环遍历每个“角色”子元素
有什么想法吗
为了启发大家,这里是我迄今为止拥有的超级简单控制器:
$f = base_url().'data/people.xml';
$p = new XMLReader;
$p->open($f);
while($p->read())
{
if($this->_notImported('govtrack',$p->getAttribute('id')))
{
// here I just grab the attributes, put them into arrays to insert, like so:
$insert = array('indiv_name' => $full_name,
'indiv_first' => ($p->getAttribute(‘firstname’)),
'indiv_last' => ($p->getAttribute(‘lastname’)),
'indiv_middle' => ($p->getAttribute(‘middlename’)),
'indiv_other' => ($p->getAttribute(‘namemod’)),
'indiv_full_name' => $full_name,
'indiv_title' => ($p->getAttribute(‘title’)),
'indiv_dob' => ($p->getAttribute(‘birthday’)),
'indiv_gender' => ($p->getAttribute(‘gender’)),
'indiv_religion' => ($p->getAttribute(‘religion’)),
'indiv_url' => ($url)
);
对于元素来说,这并没有那么困难,但我不知道如何循环遍历每个“角色”子元素并分别获取属性。您的第一个问题是没有检查适当的节点类型,这实际上与您链接的注释有关:它与开头标记(元素)都匹配和结束标记(结束元素) 您的第二个问题也与缺少节点类型检查有关。修复后,只需检查节点的名称,以确定它是
还是
因为我假设您也在读取一个大的XML文件,所以您可能想知道何时传递给下一个person标记。。。(通过END_元素nodeType)参见下面的示例:
while($p->read()) {
// check for nodeType here (opening tag only)
if ($p->nodeType == XMLReader::ELEMENT) {
if ($p->name == 'person') {
if ($this->_notImported('govtrack',$p->getAttribute('id'))) {
// $insert['indiv_*'] stuff here
} else {
$insert = null; // skip record because it's already imported
}
} else if ($p->name == 'role') {
// role stuff here
$startdate = $p->getAttribute('startdate');
}
// check for closing </person> tag here
} else if ($p->nodeType == XMLReader::END_ELEMENT && $p->name == 'person') {
if (isset($insert)) {
// db insert here
}
}
}
while($p->read()){
//在此处检查节点类型(仅限开始标记)
如果($p->nodeType==XMLReader::ELEMENT){
如果($p->name=='person'){
如果($this->\u notImported('govtrack',$p->getAttribute('id')){
//$insert['indiv\*']在此处插入内容
}否则{
$insert=null;//跳过记录,因为它已导入
}
}如果($p->name=='role'){
//这里的角色
$startdate=$p->getAttribute('startdate');
}
//检查此处的结束标记
}如果($p->nodeType==XMLReader::END_元素&&$p->name==person'),则为else{
如果(isset($insert)){
//在这里插入数据库
}
}
}
顺便说一句,如果你想让它起作用,你的引号必须用正确的引号替换。太棒了!!我在内存分配方面仍然有一些问题,但这工作得更好,我想我已经走上了让它工作的轨道。(我不确定我的引用发生了什么;它们在我的实际代码中是正确的,只是不是如此)。
$f = base_url().'data/people.xml';
$p = new XMLReader;
$p->open($f);
while($p->read())
{
if($this->_notImported('govtrack',$p->getAttribute('id')))
{
// here I just grab the attributes, put them into arrays to insert, like so:
$insert = array('indiv_name' => $full_name,
'indiv_first' => ($p->getAttribute(‘firstname’)),
'indiv_last' => ($p->getAttribute(‘lastname’)),
'indiv_middle' => ($p->getAttribute(‘middlename’)),
'indiv_other' => ($p->getAttribute(‘namemod’)),
'indiv_full_name' => $full_name,
'indiv_title' => ($p->getAttribute(‘title’)),
'indiv_dob' => ($p->getAttribute(‘birthday’)),
'indiv_gender' => ($p->getAttribute(‘gender’)),
'indiv_religion' => ($p->getAttribute(‘religion’)),
'indiv_url' => ($url)
);
while($p->read()) {
// check for nodeType here (opening tag only)
if ($p->nodeType == XMLReader::ELEMENT) {
if ($p->name == 'person') {
if ($this->_notImported('govtrack',$p->getAttribute('id'))) {
// $insert['indiv_*'] stuff here
} else {
$insert = null; // skip record because it's already imported
}
} else if ($p->name == 'role') {
// role stuff here
$startdate = $p->getAttribute('startdate');
}
// check for closing </person> tag here
} else if ($p->nodeType == XMLReader::END_ELEMENT && $p->name == 'person') {
if (isset($insert)) {
// db insert here
}
}
}