#php #xml #simplexml
#php #xml — файл #simplexml #xml
Вопрос:
У меня есть фрагмент XML, который выглядит следующим образом
<records count="2">
<record>
<firstname>firstname</firstname>
<middlename>middlename</middlename>
<lastname>lastname</lastname>
<namesuffix/>
<address>
<street-number>demo</street-number>
<street-pre-direction/>
<street-name>demo</street-name>
<street-post-direction/>
<street-suffix>demo</street-suffix>
<city>demo</city>
<state>NY</state>
<zip>demo</zip>
<zip4>demo</zip4>
<county>demo</county>
</address>
<phonenumberdetails>
<phonenumber>demo</phonenumber>
<listed>demo</listed>
<firstname>demo</firstname>
</phonenumberdetails>
<dob day="" month="" year=""/>
<age/>
<date-first month="10" year="1999"/>
<date-last month="04" year="2011"/>
</record>
<record>
<firstname>firstname</firstname>
<middlename>middlename</middlename>
<lastname>lastname</lastname>
<namesuffix/>
<address>
<street-number>demo</street-number>
<street-pre-direction/>
<street-name>demo</street-name>
<street-post-direction/>
<street-suffix>demo</street-suffix>
<city>demo</city>
<state>NY</state>
<zip>demo</zip>
<zip4>demo</zip4>
<county>demo</county>
</address>
<phonenumberdetails>
<phonenumber>demo</phonenumber>
<listed>demo</listed>
<firstname>demo</firstname>
</phonenumberdetails>
<dob day="" month="" year=""/>
<age/>
<date-first month="10" year="1999"/>
<date-last month="04" year="2011"/>
</record>
</records>
Теперь я смог получить все данные в PHP с использованием SimpleXML, за исключением элементов date-first и date-last. Я использовал код, приведенный ниже
$dateFirst = 'date-first';
$dateLast = 'date-last';
$streetNumber = 'street-number';
$streetPreDirection = 'street-pre-direction';
$streetName = 'street-name';
$streetPostDirection = 'street-post-direction';
$streetSuffix = 'street-suffix';
$unitDesignation = 'unit-designation';
$unitNumber = 'unit-number';
foreach ($reportDataXmlrecords->records->record as $currentRecord) {
echo $currentRecord->$dateFirst['month'].'/'.$currentRecord->$dateFirst['year'];
echo $currentRecord->$dateLast['month'].'/'.$currentRecord->$dateLast['year'];
echo $currentRecord->address->$streetNumber;
$currentRecord->address->$streetName; // ......and so on
}
где $reportDataXmlrecords
— часть объекта SimpleXML из родительского узла
Но первые два echo ничего не печатают, а все остальные печатаются правильно, в частности, я не могу получить доступ к данным в
<date-first month="10" year="1999"/>
<date-last month="04" year="2011"/>
Также для отладки, если я делаю
print_r($currentRecord->$dateFirst);
он печатает
SimpleXMLElement Object (
[@attributes] => Array ( [month] => 10 [year] => 1999 )
)
Мы были бы очень признательны за любую помощь. Спасибо.
Комментарии:
1. Я предполагаю, что для этого вопроса потребуется некоторая помощь в форматировании.
2. что вы получите, если вместо echo вы добавите var_dump date-first и date-last?
3. @GordonM Если я это сделаю
var_dump($currentRecord->$dateFirst);
, я получуobject(SimpleXMLElement)#32 (1) { ["@attributes"]=> array(2) { ["month"]=> string(2) "10" ["year"]=> string(4) "1999" } }
Ответ №1:
Ваша проблема заключается в том, когда вы делаете
$currentRecord->$dateFirst['month']
PHP сначала оценит $dateFirst['month']
в целом, прежде чем пытаться использовать его как свойство
$dateFirst = 'date-first';
var_dump( $dateFirst['month'] ); // gives "d"
поскольку к строкам можно получить доступ с помощью смещения с обозначением массива, но нецелочисленные смещения преобразуются в целое число, и поскольку преобразование ‘month’ в integer равно 0, вы пытаетесь сделать $currentRecord->d
:
$xml = <<< XML
<record>
<date-first month="jan"/>
<d>foo</d>
</record>
XML;
$record = simplexml_load_string($xml);
$var = 'date-first';
echo $record->$var['month']; // foo
Вы можете получить доступ к свойствам, разделенным дефисами, с помощью фигурных скобок:
$record->{'date-first'}['month'] // jan
Что касается примечания, когда XML, показанный в вашем вопросе, действительно является XML, который вы загружаете с помощью SimpleXML, например, когда <records>
является корневым узлом, тогда выполните
$reportDataXmlrecords->records->record
не может работать, потому что $reportDataXmlrecords
это уже корневой узел, и вам пришлось бы опустить ->records
, если вы хотите выполнить итерацию по элементам записи в нем.
Комментарии:
1. правильно, <records> не является корневым узлом, я добавлю исправление к вопросу. И спасибо за отличный ответ, это здорово, я узнал кое-что новое. Просто чтобы упомянуть,
$record->{'dateFirst'}['month'] // jan
я думаю, вы имели в виду$record->{'date-first'}['month'] // jan
, что второй экземпляр сработал для меня. Возможно, это была опечатка