Jump to content

Creat cdata Inside Loop Without Creating Multiple cdata


Go to solution Solved by Jacques1,

Recommended Posts

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'].

 

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?

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.

  • Solution

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.

  • Like 1

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.

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.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.