Не удается получить доступ к узлу XML с помощью xpath (проблема с пространством имен?)

У меня есть небольшая часть экспорта xml из cms под названием tridion, и я хотел бы проанализировать эту информацию с помощью php.

Я пытался с помощью DOMDocument а также DOMXPath получить доступ к данным, но не удается получить необходимую информацию.

Например, когда я пытаюсь получить доступ к узлу заглавие из моего примера данных я не получаю никакого результата.

$xmlDoc = new DOMDocument();
$xmlDoc->load($xmlFilePath);

$xpath = new DOMXPath($xmlDoc);
$xpath->registerNamespace('tcm', 'http://www.tridion.com/ContentManager/5.0');
$xpath->registerNamespace('xmlns', 'http://www.w3.org/1999/xlink');
$result = $xpath->query('title');

Я считаю, что это проблема пространства имен, но я не совсем понимаю, как с этим справиться.

Вот как выглядят файлы экспорта (несколько сокращены для удобства чтения):

<PackageItem xmlns:tcm="http://www.tridion.com/ContentManager/5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.sdltridion.com/ContentManager/ImportExport/Package/2013">
<PrimaryBlueprintParentUrl>/webdav/Content%20%28en%29/Content/120_external%20Links/Services/EL_www%2some-domin%2Ecom.xml</PrimaryBlueprintParentUrl>
<Data>
<tcm:Data>
<tcm:Title>EL_www.some-domain.com</tcm:Title>
<tcm:Type>Normal</tcm:Type>
<tcm:Schema xlink:type="simple" xlink:title="External Link (EL)" xlink:href="/webdav/Content/System/Schemas/Common/External%20Link%20%28EL%29.xsd" IsMandatory="false" />
<tcm:Content>
<externallink xmlns="uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8">
<title>www.some-domain.com</title>
<url xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.some-domain.com" />
</externallink>
</tcm:Content>
</tcm:Data>
</Data>
</PackageItem>

0

Решение

<externallink> элемент непосредственно перед тем, как он определяет пространство имен по умолчанию для него и <title> элемент как xmlns="uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8", Так что, если вы определите это пространство имен (я просто использую фиктивное — d), а затем использовать это в своем выражении …

$xpath->registerNamespace('d', "uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8");
$result = $xpath->query('//d:title');

Обновить…

Для URL …

$result = $xpath->query('//d:url');

echo $xmlDoc->saveXML($result[0]);

Дает …

<url xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.some-domain.com"/>

Так как это не имеет значения как такового (я только что сказал вывод XML первого найденного узла), не уверен, что вам нужно из него.

Если вы просто хотите атрибут href …

echo $result[0]->getAttribute("xlink:href");
1

Другие решения

Вы пропустили регистрацию псевдонимов для правильных пространств имен. Вот определение пространства имен для элемента externallink для пространства имен uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8, Синтаксический анализатор XML понимает этот узел как {uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8}externallink и title дочерний элемент как {uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8}title, Все 3 следующих примера разрешают title узел такой:

  • <title xmlns="uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8"/>
  • <t:title xmlns:t="uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8"/>
  • <el:title xmlns:el="uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8"/>

Регистрируя псевдонимы на DOMXpath Например, вы позволяете ему сделать то же самое для выражения.

$xpath->registerNamespace('e', 'uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8');

e:title -> {uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8}title

Xpath 1.0 не имеет пространства имен по умолчанию, поэтому вам придется зарегистрировать псевдоним для любого пространства имен, которое вы хотите использовать в выражении.

тем не мение e:title будет искать только дочерние узлы. Для просмотра любого узла в документе используйте //e:title, Стартовый / привязывает выражение к самому документу (а не к текущему контекстному узлу). Второй / меняет ось от child в descendant,
использование string() привести первый соответствующий узел в строку и вернуть его:

$xpath = new DOMXPath($xmlDoc);
$xpath->registerNamespace('e', 'uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8');
var_dump($xpath->evaluate('string(//e:title)'));

Выход:

string(19) "www.some-domain.com"

DOMXpath::query() может возвращать только списки узлов, DOMXpath::evaluate() также может возвращать скалярные значения.

Для xlink:href атрибут, который необходимо зарегистрировать и в этом пространстве имен:

$xpath = new DOMXPath($xmlDoc);
$xpath->registerNamespace('e', 'uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8');
$xpath->registerNamespace('xlink', 'http://www.w3.org/1999/xlink');
var_dump($xpath->evaluate('string(//e:url/@xlink:href)'));

Выход:

string(26) "http://www.some-domain.com"
1

По вопросам рекламы [email protected]