Это было довольно сложно понять. Я упростил структуру, чтобы мы могли видеть части иерархии, которые нас интересуют.
Похоже, что NewsComponent, имеющий атрибут Duid , определяет / содержит одну полную новость. Из двух дочерних элементов NewsComponent первого содержит сводку и текст, а второй дочерний NewsComponent содержит изображение.
Ваш первоначальный запрос XPath предназначен для 'NewsItem/NewsComponent/NewsComponent/NewsComponent'
, который является первым дочерним элементом NewsComponent (тот, который содержит основной текст). Вы не можете найти изображение с этой точки, потому что изображение не находится внутри этого NewsComponent; Вы прошли один уровень слишком глубоко. (Я был предупрежден тем фактом, что получил PHP Примечание: неопределенная переменная: dbImage .) Таким образом, отбросьте ваш первоначальный запрос XPath обратно на уровень и добавьте этот дополнительный уровень к вашим последующим запросам XPath, где это необходимо.
Из этого:
$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent');
foreach($story as $contentItem){
foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.content/p') as $detail){
foreach($contentItem->xpath('NewsComponent/NewsComponent/ContentItem') as $imageNode){ /* ... */ }}}}
к этому:
$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent');
foreach($story as $contentItem){
foreach($contentItem->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
foreach($contentItem->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.content/p') as $detail){
foreach($contentItem->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem') as $imageNode){ /* ... */ }}}}
Однако изображение все равно не работает после этого. Поскольку вы используете циклы (иногда без необходимости), $dbImage
переназначается на пустую строку. Первый ContentItem имеет атрибут Href , который присваивается $dbImage
. Но затем он возвращается к следующему ContentItem, который не имеет атрибутов и поэтому перезаписывает $dbImage
пустым значением. Я бы порекомендовал изменить этот запрос XPath, чтобы найти только ContentItems, имеющие атрибут Href , например:
->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem[@Href]')
Это должно сделать это.
Другие мысли
Рефакторинг для очистки этого кода, если / где это возможно.
Как я уже упоминал, иногда вы зацикливаетесь и вкладываете, когда вам это не нужно, и вам просто становится сложнее следить и потенциально вносить логические ошибки (как на изображении). Кажется, что структура этого файла всегда будет согласованной. Если это так, вы можете отказаться от некоторых циклов и перейти к нужным фрагментам данных. Вы могли бы сделать что-то вроде этого:
// Get story header & detail
$stories = $xml->xpath('/NewsML/NewsItem/NewsComponent/NewsComponent');
foreach ($stories as $story) {
$headlineItem = $story->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.head/hedline/hl1');
$headline = $headlineItem[0];
$detailItems = $story->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.content/p');
$strDetail = '<p>' . implode('</p><p>', $detailItems) . '</p>';
$imageItem = $story->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem[@Href]');
$imageAtts = $imageItem[0]->attributes();
$dbImage = $imageAtts['Href'];
$link = getUnique($headline);
$sql = "INSERT INTO tablename (headline, detail, image, link) VALUES ('".mysql_real_escape_string($headline)."', '".mysql_real_escape_string($strDetail)."', '".mysql_real_escape_string($dbImage)."', '".$link."')";
if (mysql_query($sql, $db) or die(mysql_error())) {
echo "Loaded ";
} else {
echo "Not Loaded ";
}
}