1

I am trying to change my model to xml format.

I did almost everything but I still need this thing:

$data = [
            'domain'=> $xmlDocument->domain,
            'FirstDate' => $xmlDocument->dateAttribute->first_date,
            'LastDate' => $xmlDocument->dateAttribute->last_date,
            'Category' => $xmlDocument->category->name,
            'Action' => $xmlDocument->websiteAction->name,
            'Source' => $xmlDocument->source->name,
            'LogFile' => $xmlDocument->log_file,
            'DateAttribute' => [
                        'Name' => $xmlDocument->dateAttribute->name,
                        'Place' => $xmlDocument->dateAttribute->dateLocation->name,
                        'DateFunction' => $xmlDocument->dateAttribute->dateFunction->name
                    ],
            'MasterPage' => [
                'MasterAttributes' => [

                ],
                'Container'=>[
                    'xpath' => $xmlDocument->masterInformation->xpath
                ],
                'NextPage' =>[],
                'LinkAttribute'=>[]
            ],
        ];

as you see the MasterAttributes is empty.

the model $xmlDocument has a one to many relationship like this:

$xmlDocument->masterInformaton->masterAttributes

the masterAttributes is the many part

My question

how to use that many and transfer it to array, so each element in that array is this:

'masterAttribute' => [
    'name' => ...,
    'xpath' => ...
]

In other words, I will have many arrays and these arrays will be added to the empty MasterAttribute key in the code I showed to u.

I hope I made my point to you, if not, kindly tell me.

Update

What I have tried:

$masterAttributes = [];
        foreach ($xmlDocument->masterInformation->masterAttributes as $attribute){
            $masterAttribute = [
                'Attribute' =>[
                    'defaultValue' => $attribute->defaultValue,
                    'name' => $attribute->attributeName->name,
                    'xpath' => $attribute->xpath
                ]
            ];
            array_push($masterAttributes, $masterAttribute);
        }

and then I put the result like this:

'MasterAttributes' => [
                    $masterAttributes
                ],

but the generated xml is:

<MasterAttributes>
         <item0>
            <item0>
               <Attribute>
                  <defaultValue />
                  <name>bathroom</name>
                  <xpath>this is the xpath</xpath>
               </Attribute>
            </item0>
            <item1>
               <Attribute>
                  <defaultValue />
                  <name>price</name>
                  <xpath>new xpath</xpath>
               </Attribute>
            </item1>
            <item2>
               <Attribute>
                  <defaultValue />
                  <name>bathroom</name>
                  <xpath>new xpath value</xpath>
               </Attribute>
            </item2>
         </item0>
      </MasterAttributes>

look that there is extra Item2 and item0 that I don't want

Update 2

The code to generate the xml is:

$xml = new SimpleXMLElement("<?xml version=\"1.0\"?><websiteInformation></websiteInformation>");
        $this->array_to_xml($data,$xml);
        $xml->asXML("FileName".XmlDocument::find($id)->id.".xml");

where $data is the final array I showed to you and array_to_xml is:

// function defination to convert array to xml
    public  function array_to_xml($student_info, &$xml_student_info) {
        foreach($student_info as $key => $value) {
            if(is_array($value)) {
                if(!is_numeric($key)){
                    $subnode = $xml_student_info->addChild("$key");
                    $this->array_to_xml($value, $subnode);
                }
                else{
                    $subnode = $xml_student_info->addChild("item$key");
                    $this->array_to_xml($value, $subnode);
                }
            }
            else {
                $xml_student_info->addChild("$key",htmlspecialchars("$value"));
            }
        }
    }

Updadte 3

The @watcher gave me an aswer and this is the result of his/her answer

<MasterAttributes>
         <item0>
            <masterAttribute>
               <name />
               <xpath>this is the xpath</xpath>
            </masterAttribute>
         </item0>
         <item1>
            <masterAttribute>
               <name />
               <xpath>new xpath</xpath>
            </masterAttribute>
         </item1>
         <item2>
            <masterAttribute>
               <name />
               <xpath>new xpath value</xpath>
            </masterAttribute>
         </item2>
      </MasterAttributes>

1 Answer 1

1

Try something like this:

$attributes = $xmlDocument->masterInformaton->masterAttributes;
foreach($attributes as $attribute) {
    $data['MasterPage']['MasterAttributes'][] = [
        'masterAttribute' => [
            'name' => $attribute->name,
            'xpath' => $attribute->xpath,
        ]
    ];
}

This is assuming that the attributes on your master attributes are name and xpath.

Update

$subnode = $xml_student_info->addChild("item$key");

This is the line in your xml generation that is adding those item0 nodes. Removing that doesn't help, because you do need to build a subtree based off of these indices, but you don't want to add them directly to the XML document as they are.

I tried coming up with a quick solution, but it turns out its not so quick (I also found I think the original answer where you found your xml generation code here).

Update 2

Try using this for your xml generation, see if it gets you what you need. It's based off of this answer by @drzaus:

function simple_xmlify($arr, SimpleXMLElement $root = null, $el = 'x') {
    // based on, among others https://stackoverflow.com/a/1397164/1037948

    if(!isset($root) || null == $root) $root = new SimpleXMLElement('<' . $el . '/>');

    if(is_array($arr)) {
        foreach($arr as $k => $v) {
            // special: attributes
            if(is_string($k) && $k[0] == '@') $root->addAttribute(substr($k, 1),$v);
            // normal: append
            else {
                if(is_numeric($k) && is_array($v)) {
                    foreach($v as $ik => $iv) {
                        simple_xmlify($iv, $root);
                    }
                } else {
                    simple_xmlify($v, $root->addChild(
                        // fix 'invalid xml name' by prefixing numeric keys
                        is_numeric($k) ? 'n' . $k : $k)
                    );
                }

            }
        }
    } else {
        $root[0] = $arr;
    }

    return $root;
}//--   fn  simple_xmlify
Sign up to request clarification or add additional context in comments.

14 Comments

I just updated the question before I saw you answer and it seems that I was doing close to your answer, let me test it and I will update you +1 anyway
I updated the answer a bit, trying to get it to match what you stated you want the output to be in better.
I dont' know but the answer has not been updated yet. are you sure you have?
Yes, it was a slight change. I assume you're using foreach to iterate through the array to generate the xml, and I think the reason you're getting those extra keys is due to numeric indices that you're wanting to not include as xml elements. Can you update the question with the code you're using to generate the xml?
but how to put your result in my final array?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.