我需要从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
来实现?
答案 0 :(得分:2)
好像您从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;
答案 1 :(得分:2)
作为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;
}