У меня есть небольшая часть экспорта 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>
<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");
Вы пропустили регистрацию псевдонимов для правильных пространств имен. Вот определение пространства имен для элемента 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"