我从一个叫做Tridion的cms导出的xml中有一小部分,我想使用php解析此信息。
我尝试使用DOMDocument
和DOMXPath
访问数据,但是未能检索到所需的信息。
例如,当我尝试从示例数据访问节点 title 时,没有任何结果。
$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 :(得分:1)
之前的<externallink>
元素为其定义了默认名称空间,而<title>
元素为xmlns="uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8"
。因此,如果您定义此命名空间(我只使用一个虚拟的-d
),然后在您的表达式中使用它...
$xpath->registerNamespace('d', "uuid:D612E2C9-CD2E-4CD8-9FAE-3826311343A8");
$result = $xpath->query('//d:title');
更新...
对于网址...
$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 :(得分: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"