codeinphp Posted August 15, 2016 Share Posted August 15, 2016 Is it possible to append to cdatasection within xml file using a loop without creating a new cdata section with each loop thru. The code starts out by creating the basics for xml then enters into a loop to go thru each element of an array, appending the cdata. $xml=new DOMDocument('1.0', 'UTF-8'); $xml->preserveWhiteSpace = false; $xml->formatOutput = true; $components = $xml->createElement("components"); $name=$xml->createAttribute("name"); $name->value = "customEPGGrid"; $extends=$xml->createAttribute("extends"); $extends->value = "EPGGrid"; $components->appendChild($name); $components->appendChild($extends); $script = $xml->createElement("script"); $type=$xml->createAttribute("type"); $type->value = "text/brightscript"; foreach ($items as $item){ //ENTER INTO LOOP $cdata=$xml->createCDATASection(<<<EOT function init() m.content = createObject("RoSGNode","ContentNode") m.top.setFocus(true) dateNow = CreateObject("roDateTime") dateNow = dateNow.asSeconds() - 2000 addChannel({$item['name']}) addItem({$item['name']}, dateNow) m.top.content = m.content m.top.translation = [50, 300] m.top.numRows = 5 m.top.duration = 10800 m.top.nowNextMode = false m.top.infoGridGap = 0 m.top.channelInfoColumnLabel = "HELLO" end function sub addChannel(channelText as string) m.channel = m.content.createChild("ContentNode") m.channel.TITLE = channelText m.channel.HDSMALLICONURL = "http://css.boshanka.co.uk/wp-content/uploads/2015/04/icon-logo-design-small.png" end sub sub addItem(progText as string, timeStart) For i=0 To 5 Step 1 program = m.channel.createChild("ContentNode") program.TITLE = progText + str(i) program.PLAYSTART = timeStart + (i * 2000) program.PLAYDURATION = "2000" End For end sub EOT ); } $script->appendChild($cdata); $script->appendChild($type); $components->appendChild($script); $xml->appendChild($components); $xml->save($filename2); When executed like this, I get a new createCDATASection with each pass thru the loop. Not really wanting this, but one createCDATASection with different value or $item['name']. Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/ Share on other sites More sharing options...
Jacques1 Posted August 15, 2016 Share Posted August 15, 2016 This is a bad approach in general. You shouldn't generate scripting code, because this can easily lead to syntax errors and security vulnerabilities. I have no idea how this “BrightScript” works, but the ideal solution would be to insert the items as XML nodes (i. e. as data) and then access this data with BrightScript: <items> <item>foo</item> <item>bar</item> <item>baz</item> </items> <script type="text/brightscript"> Each item in obtain_items() addChannel(item) addItem(item, dateNow) </script> You get the idea. Is this possible? Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/#findComment-1536188 Share on other sites More sharing options...
codeinphp Posted August 15, 2016 Author Share Posted August 15, 2016 Not completely sure, will have to look over and see if possible. The xml being generated is basically a template that a component of Brightscript (for Roku) will read when loading. All elements of the generated xml would never change, only the addChannel and add Item info. The addChannel info is all generated thru a php script I have written that parses out xml info from multiple xml files and puts them together. I had been saving all the info into a json array file and have the Roku read the json array. The creators of Roku have developed a new component that allows developers create screens thru xml templates, one being the one I am working with. I will see if I can create xml nodes and see if this works. Have a feeling the Brightscript component is setup to read the template a certain way and may not recognize the information. Thanks for the idea. Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/#findComment-1536192 Share on other sites More sharing options...
Solution Jacques1 Posted August 15, 2016 Solution Share Posted August 15, 2016 If it's not possible to get additional XML data into the application, you have to carefully validate/escape the input and then insert it into the script: // *not* recommended; this can lead to syntax errors and code injections $channels_script = ''; foreach ($items as $item) { /* * TODO: validate $item and make sure that it won't interfere with the script * Ideally, it should be restricted to alphanumerical characters and spaces */ $safe_item = brightscript_validate($item); $channels_script .= ' addChannel("'.$safe_item.'") addItem("'.$safe_item.'", dateNow) '; } $cdata = $xml->createCDATASection(' function init() print "inside epg" m.content = createObject("RoSGNode","ContentNode") m.top.setFocus(true) dateNow = CreateObject("roDateTime") dateNow = dateNow.asSeconds() - 2000 '.$channels_script.' m.top.content = m.content m.top.translation = [50, 300] m.top.numRows = 5 m.top.duration = 10800 m.top.nowNextMode = false m.top.infoGridGap = 0 m.top.channelInfoColumnLabel = "Hello" end function'); But again, this is for the worst case scenario. 1 Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/#findComment-1536194 Share on other sites More sharing options...
codeinphp Posted August 15, 2016 Author Share Posted August 15, 2016 Thanks for taking the time to look at this. In your example code won't the $cdata only contain the last value of $safe_item once the loop is finished? I was trying something like your example by the only way I could get each value of $safe_item into the $cdata was to include the $cdata in the loop, which of course creates a new instance of createDataSection with each loop. Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/#findComment-1536196 Share on other sites More sharing options...
Jacques1 Posted August 15, 2016 Share Posted August 15, 2016 The loop creates a long string of the kind addChannel("item1") addItem("item1", dateNow); addChannel("item2") addItem("item2", dateNow); addChannel("item3") addItem("item3", dateNow); ... And this is inserted into the main script. Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/#findComment-1536197 Share on other sites More sharing options...
codeinphp Posted August 16, 2016 Author Share Posted August 16, 2016 Thanks again, I see adding the . just before = conecates the string. Had not thought of that, thank very much. Quote Link to comment https://forums.phpfreaks.com/topic/301900-creat-cdata-inside-loop-without-creating-multiple-cdata/#findComment-1536206 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.