我需要从XML中保存一些值。
第一步 - 我得到结构:
$xml = $dom_xml->saveXML();
$xml_ = new \SimpleXMLElement($xml);
dd($xml_);
这里TextFrame
有8个阵列。他们每个都有PathPointType
,它有4个阵列,每个阵列有3个属性。我需要从每个TextFrame
这些属性。
例如,我可以得到Anchor
值这样做:
$res = $xml_
->Spread
->TextFrame
->Properties
->PathGeometry
->GeometryPathType
->PathPointArray
->PathPointType
->attributes();
dd($res['Anchor']);
(顺便说一句:是否有更漂亮的方式来获得它?)
但问题是 - 如何循环遍历所有数组并为每个数组单独保存值?
我假设这里必须是一个多维foreach
循环与for
循环?
或者使用DOMDocument
更好地实现它?
看起来好像你开始使用DOMDocument(因为你使用$dom_xml->saveXML()
来生成XML),它可能更容易继续使用它,它也有一些简单的功能,可以让你获得详细信息。
使用getElementsByTagName()
可以从起点获得具有特定标记名称的元素列表,因此从$dom_xml
开始,获取所有<TextFrame>
元素。然后foreach()
在此列表上并使用此元素作为起点,使用getElementsByTagName("PathPointType")
获取嵌套的<PathPointType>
元素。此时,您可以使用getAttribute("Anchor")
为<PathPointType>
元素所需的每个属性...
$textFrames = $dom_xml->getElementsByTagName("TextFrame");
foreach ( $textFrames as $frame ) {
$pathPointTypes = $frame->getElementsByTagName("PathPointType");
foreach ( $pathPointTypes as $type ) {
echo $type->getAttribute("Anchor").PHP_EOL;
}
}
编辑
您可以扩展代码以构建一个框架数组,然后在其中构建锚点。此代码还将锚存储在关联数组中,以便在添加其他属性时,可以在此处添加它们(如果不需要其他详细信息,则将其删除)...
$frames =[];
foreach ( $textFrames as $frame ) {
$anchors = [];
$pathPointTypes = $frame->getElementsByTagName("PathPointType");
foreach ( $pathPointTypes as $type ) {
$anchors[] = ['Anchor' => $type->getAttribute("Anchor")];
}
$frames[] = $anchors;
}
此外,如果您有某种方法来识别帧,您也可以在该级别创建一个关联数组......
$frames[$frameID] = $anchors;
作为the existing answer from Nigel Ren的补充,我想我会用SimpleXML展示相同的循环。
首先,请注意,如果您因任何原因想要在DOM和SimpleXML之间切换,则不需要将XML转换为字符串并返回,您可以使用仅交换接口的simplexml_import_dom:
$sxml = simplexml_import_dom($dom_xml);
接下来我们需要我们的TextFrame
元素;我们可以像以前一样明确地逐步完成结构:
$textFrames = $sxml->Spread->TextFrame;
或者我们可以使用XPath在当前节点中搜索匹配的标记名称(.
是当前元素,而//
表示“任何后代”:
$textFrames = $sxml->xpath('.//TextFrame');
第一个会给你一个SimpleXMLElement
对象,第二个会给你一个数组,但无论哪种方式,你都可以使用foreach
来完成比赛。
这次我们肯定想要一个XPath表达式来获取PathPointType
节点,以避免所有嵌套循环通过我们不感兴趣的级别:
foreach ( $textFrames as $frame ) {
$pathPointTypes = $frame->xpath('.//PathPointType');
foreach ( $pathPointTypes as $type ) {
echo $type['Anchor'] . PHP_EOL;
}
}
请注意,您无需致电$type->attributes()
;除非你正在处理名称空间,否则你需要获得一个属性就是$node['AttributeName']
。请注意,SimpleXML中的属性是对象,因此您通常希望强制它们成为(string)$node['AttributeName']
的字符串。
举一个最后的例子,你可能会有这样的事情:
$frames = [];
foreach ( $sxml->Spread->TextFrame as $frame ) {
$anchors = [];
$pathPointTypes = $frame->xpath('.//PathPointType');
foreach ( $pathPointTypes as $type ) {
$anchors[] = ['Anchor' => (string)$type['Anchor']];
}
$frames[] = $anchors;
}