Php 数组到xml-重复标记的问题

Php 数组到xml-重复标记的问题,php,xml,parsing,multidimensional-array,Php,Xml,Parsing,Multidimensional Array,已编辑 我试图将表单输入放入xml文件中 搜索,我用它来解析$\u帖子内容 经过几次尝试后,我意识到“数字标记”(由非关联数组产生)可能是我失败的原因,因此我修改了代码如下: function array_to_xml(array $arr, SimpleXMLElement $xml, $NumK = false) { foreach ($arr as $k => $v) { if (is_array($v)){ preg_match('/

已编辑
我试图将表单输入放入xml文件中

搜索,我用它来解析$\u帖子内容

经过几次尝试后,我意识到“数字标记”(由非关联数组产生)可能是我失败的原因,因此我修改了代码如下:

function array_to_xml(array $arr, SimpleXMLElement $xml, $NumK = false)
{
    foreach ($arr as $k => $v) {
        if (is_array($v)){
            preg_match('/^0|[1-9]\d*$/', implode(array_keys($v)))
            ? array_to_xml($v, $xml->addChild($k), true)
            : array_to_xml($v, $xml->addChild($k));
        }else{
            $NumK
            ? $xml->addChild('_'.$k.'_', $v)
            : $xml->addChild($k, $v);
        }
    }
    return $xml;
}
无论如何,我仍然在使用xpath命令进行“斗争”,因为我无法找到需要转换为重复标记的某些节点(来自非关联数组)的祖辈

这就是我试图遵循的逻辑:
第一个-查找要重新格式化的节点(唯一具有数字标记的节点)
第二个-找到祖父母(我需要重复标签)
第三-用祖父母的标签替换祖父母(及其后代),每组孙辈(每个孩子一个)

到目前为止,由于xpath误解,我仍然停留在第一步

下面是我得到的xml结果以及如何转换它:

我的数组类似于:

$TestArr = Array
    ("First" => array
        ("Martha" => "Text01"
        ,
        "Lucy" => "Text02"
        ,
        "Bob" => array 
            ("Jhon" => array
                ("01", "02")
            ),
        "Frank" => "One"
        ,
        "Jessy" => "Two"
        )
    ,
    "Second" => array
        ("Mary" => array 
            ("Jhon" => array
                ("03", "04")
            ,
            "Frank" => array
                ("Three", "Four")
            ,
            "Jessy" => array
                ("J3", "J4")
            )
        )
    );
使用函数
array\u to\u xml($TestArr,new simplexmlement(“”))
我得到一个类似以下的xml:

<root>
    <First>
        <Martha>Text01</Martha>
        <Lucy>Text02</Lucy>
        <Bob>
            <Jhon>
                <_0_>01</_0_>
                <_1_>02</_1_>
            </Jhon>
        </Bob>
        <Frank>One</Frank>
        <Jessy>Two</Jessy>
    </First>
    <Second>
        <Mary>
            <Jhon>
                <_0_>03</_0_>
                <_1_>04</_1_>
            </Jhon>
            <Frank>
                <_0_>Three</_0_>
                <_1_>Four</_1_>
            </Frank>
            <Jessy>
                <_0_>J3</_0_>
                <_1_>J4</_1_>
            </Jessy>
        </Mary>
    </Second>
</root>

Text01
Text02
01
02
一个
两个
03
04
三
四
J3
J4
我需要的结果是:

<root>
    <First>
        <Martha>Text01</Martha>
        <Lucy>Text02</Lucy>
            <Bob>
                <Jhon>01</Jhon>
            </Bob>
            <Bob>
                <Jhon>02</Jhon>
            </Bob>
        <Frank>One</Frank>
        <Jessy>Two</Jessy>
    </First>
    <Second>
        <Mary>
            <Jhon>03</Jhon>
            <Frank>Three</Frank>
            <Jessy>J3</Jessy>
        </Mary>
        <Mary>
            <Jhon>04</Jhon>
            <Frank>Four</Frank>
            <Jessy>J4</Jessy>
        </Mary>
    </Second>
</root>

Text01
Text02
01
02
一个
两个
03
三
J3
04
四
J4

迭代数组值并添加具有相同键的元素

if (is_array($v)){
    foreach($v as $arr_ele){
        $xml->addChild($k, $arr_ele);
    }
}

迭代数组值并添加具有相同键的元素

if (is_array($v)){
    foreach($v as $arr_ele){
        $xml->addChild($k, $arr_ele);
    }
}

我已经更新了代码,试图更接近您试图实现的目标。我考虑了如何识别数据分组,为此,我向以这种方式添加的每个元素添加了一个“id”属性。同样为了方便起见,我为父元素设置了一个“max”计数器

第一个XPath表达式(
/*[@id]/..
)获取需要处理的所有元素。然后循环计算先前计数的子元素的数量。XPath
子体::*[@id='{$i}']
挑选出每一组元素(因此所有id='0',然后是'1'等)。这是数据的自然分组

function array_to_xml(array $arr, SimpleXMLElement $xml, string $elementName = null)
{
    foreach ($arr as $k => $v) {
        if (is_array($v)){
            if ( preg_match('/^0|[1-9]\d*$/', implode(array_keys($v)))) {
                array_to_xml($v, $xml, $k);
            }
            else    {
                array_to_xml($v, $xml->addChild($k));
            }
        }
        else    {
            if ( $elementName != null )   {
                $newElement = $xml->addChild($elementName, $v);
                $newElement["id"] = $k;
                $xml["max"] = $k;
            }
            else    {
                $xml->addChild($k, $v);
            }
        }
    }
    //return $xml;
}
$xml = new SimpleXMLElement("<root />");
array_to_xml($TestArr, $xml);
$todoList = $xml->xpath("//*[@id]/..");
foreach ( $todoList as $todo )  {
    $parent = $todo->xpath("..")[0];
    for ( $i = 0; $i <= $todo['max']; $i++ )    {
        $content = $todo->xpath("descendant::*[@id='{$i}']");
        $newName = $todo->getName();
        $new = $parent->addChild($newName);
        foreach ( $content as $addIn )  {
            $new->addChild($addIn->getName(), (string)$addIn);
        }
    }
    unset ( $parent->$newName[0]);
}

print $xml->asXML(); 
函数数组到xml(数组$arr,simplexmlement$xml,字符串$elementName=null)
{
foreach($arr为$k=>$v){
if(is_数组($v)){
如果(preg_匹配('/^0 |[1-9]\d*$/',内爆(数组键($v))){
数组到xml($v,$xml,$k);
}
否则{
数组到xml($v,$xml->addChild($k));
}
}
否则{
如果($elementName!=null){
$newElement=$xml->addChild($elementName,$v);
$newElement[“id”]=$k;
$xml[“max”]=$k;
}
否则{
$xml->addChild($k,$v);
}
}
}
//返回$xml;
}
$xml=新的SimpleXMLElement(“”);
数组到xml($TestArr,$xml);
$todoList=$xml->xpath(“/*[@id]/..”);
foreach($todo列为$todo){
$parent=$todo->xpath(“…”)[0];
对于($i=0;$i xpath(“后代::*[@id='{$i}']);
$newName=$todo->getName();
$new=$parent->addChild($newName);
foreach($内容为$addIn){
$new->addChild($addIn->getName(),(字符串)$addIn);
}
}
未设置($parent->$newName[0]);
}
打印$xml->asXML();
输出

<?xml version="1.0"?>
<root>
    <First>
        <Martha>Text01</Martha>
        <Lucy>Text02</Lucy>
        <Frank>One</Frank>
        <Jessy>Two</Jessy>
        <Bob>
            <Jhon>01</Jhon>
        </Bob>
        <Bob>
            <Jhon>02</Jhon>
        </Bob>
    </First>
    <Second>
        <Mary>
            <Jhon>03</Jhon>
            <Frank>Three</Frank>
            <Jessy>J3</Jessy>
        </Mary>
        <Mary>
            <Jhon>04</Jhon>
            <Frank>Four</Frank>
            <Jessy>J4</Jessy>
        </Mary>
    </Second>
</root>

Text01
Text02
一个
两个
01
02
03
三
J3
04
四
J4

我更新了代码,试图更接近您试图实现的目标。我考虑了如何识别数据分组,并为此向以这种方式添加的每个元素添加了一个“id”属性。此外,为了方便起见,我为父元素设置了一个“max”计数器

第一个XPath表达式(
/*[@id]/..
)获取需要处理的所有元素。然后循环计算前面计数的子元素数。XPath
子代::*[@id='{$i}]
挑选出每一组元素(因此所有id='0',然后是'1'等)。这是数据的自然分组

function array_to_xml(array $arr, SimpleXMLElement $xml, string $elementName = null)
{
    foreach ($arr as $k => $v) {
        if (is_array($v)){
            if ( preg_match('/^0|[1-9]\d*$/', implode(array_keys($v)))) {
                array_to_xml($v, $xml, $k);
            }
            else    {
                array_to_xml($v, $xml->addChild($k));
            }
        }
        else    {
            if ( $elementName != null )   {
                $newElement = $xml->addChild($elementName, $v);
                $newElement["id"] = $k;
                $xml["max"] = $k;
            }
            else    {
                $xml->addChild($k, $v);
            }
        }
    }
    //return $xml;
}
$xml = new SimpleXMLElement("<root />");
array_to_xml($TestArr, $xml);
$todoList = $xml->xpath("//*[@id]/..");
foreach ( $todoList as $todo )  {
    $parent = $todo->xpath("..")[0];
    for ( $i = 0; $i <= $todo['max']; $i++ )    {
        $content = $todo->xpath("descendant::*[@id='{$i}']");
        $newName = $todo->getName();
        $new = $parent->addChild($newName);
        foreach ( $content as $addIn )  {
            $new->addChild($addIn->getName(), (string)$addIn);
        }
    }
    unset ( $parent->$newName[0]);
}

print $xml->asXML(); 
函数数组到xml(数组$arr,simplexmlement$xml,字符串$elementName=null)
{
foreach($arr为$k=>$v){
if(is_数组($v)){
如果(preg_匹配('/^0 |[1-9]\d*$/',内爆(数组键($v))){
数组到xml($v,$xml,$k);
}
否则{
数组到xml($v,$xml->addChild($k));
}
}
否则{
如果($elementName!=null){
$newElement=$xml->addChild($elementName,$v);
$newElement[“id”]=$k;
$xml[“max”]=$k;
}
否则{
$xml->addChild($k,$v);
}
}
}
//返回$xml;
}
$xml=新的SimpleXMLElement(“”);
数组到xml($TestArr,$xml);
$todoList=$xml->xpath(“/*[@id]/..”);
foreach($todo列为$todo){
$parent=$todo->xpath(“…”)[0];
对于($i=0;$i xpath(“后代::*[@id='{$i}']);
$newName=$todo->getName();
$new=$parent->addChild($newName);
foreach($内容为$addIn){
$new->addChild($addIn->getName(),(字符串)$addIn);
}