Reputation: 915
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
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.
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
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"));
}
}
}
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>
Upvotes: 1
Views: 154
Reputation: 24661
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
Upvotes: 1