Example #1
0
 /**
  * Add the node to a position under the tree
  *
  * @param \SimpleXmlElement|Element $node
  * @param Element $parent
  */
 public function addChild($node, $parent = null)
 {
     if ($node instanceof \SimpleXmlElement) {
         $name = $node->getName();
         $attributes = (array) $node->attributes();
         $content = trim((string) $node);
         $element = new Element($name, $attributes, $content);
         if (!$this->tree) {
             $this->tree = $element;
         } else {
             if (!$parent) {
                 $parent = $this->tree;
             }
             $parent->addChild($element);
         }
         // Add child elements recursive
         if ($node->count() > 0) {
             foreach ($node as $childNode) {
                 $this->addChild($childNode, $element);
             }
         }
     } else {
         if ($node instanceof Element) {
             if (!$this->tree) {
                 $this->tree = $node;
             } else {
                 if (!$parent) {
                     $parent = $this->tree;
                 }
                 $parent->addChild($node);
             }
         }
     }
 }
Example #2
0
 /**
  * return an xml elements attributes in as array
  * @param \SimpleXmlElement $element
  * @return array
  */
 protected function readAttributesArray(\SimpleXmlElement $element)
 {
     $attributes = [];
     foreach ($element->attributes() as $attrName => $attr) {
         $attributes[$attrName] = (string) $attr;
     }
     return $attributes;
 }
 /**
  * Parse the input SimpleXmlElement into an array
  *
  * @param \SimpleXmlElement $node xml to parse
  * @return array
  */
 private function parseXml(\SimpleXmlElement $node)
 {
     $data = array();
     if ($node->attributes()) {
         foreach ($node->attributes() as $attrkey => $attr) {
             $data['@' . $attrkey] = (string) $attr;
         }
     }
     foreach ($node->children() as $key => $subnode) {
         if ($subnode->count()) {
             $value = $this->parseXml($subnode);
         } elseif ($subnode->attributes()) {
             $value = array();
             foreach ($subnode->attributes() as $attrkey => $attr) {
                 $value['@' . $attrkey] = (string) $attr;
             }
             $value['#'] = (string) $subnode;
         } else {
             $value = (string) $subnode;
         }
         if ($key === 'item') {
             if (isset($value['@key'])) {
                 $data[(string) $value['@key']] = $value['#'];
             } elseif (isset($data['item'])) {
                 $tmp = $data['item'];
                 unset($data['item']);
                 $data[] = $tmp;
                 $data[] = $value;
             }
         } elseif (array_key_exists($key, $data)) {
             if (false === is_array($data[$key]) || false === isset($data[$key][0])) {
                 $data[$key] = array($data[$key]);
             }
             $data[$key][] = $value;
         } else {
             $data[$key] = $value;
         }
     }
     return $data;
 }
 function get_purchased_themes($offset = 1, $limit = 10)
 {
     // Get the user's data from the database and authenticate it.
     $this->load_user_data();
     if ($this->is_valid) {
         $themes = array();
         $params = array('username' => $this->user, 'password' => $this->pass, 'action' => 'get_themes', 'offset' => $offset, 'limit' => $limit);
         $data = $this->get_api_data($params);
         $xmlobj = new SimpleXmlElement($data);
         if ($xmlobj) {
             // Extract the total number of themes.
             foreach ($xmlobj->attributes() as $k => $v) {
                 ${$k} = $v;
                 if ($k == 'total') {
                     $this->total_themes = $v;
                 }
                 // End IF Statement
             }
             // End FOREACH Loop
             foreach ($xmlobj as $xml) {
                 // Generate a token for this theme.
                 $_name_bits = explode(' - ', $xml->name);
                 $_key = urlencode(strtolower($_name_bits[0]));
                 $_key = str_replace('+', '', $_key);
                 $name_solo = $_name_bits[0];
                 $package_type = $_name_bits[1];
                 $_year = substr($xml->launch_date, 0, 4);
                 $_month = substr($xml->launch_date, 5, 2);
                 $_day = substr($xml->launch_date, 8, 2);
                 $timestamp = date("Y-m-d", mktime(0, 0, 0, $_month, $_day, $_year));
                 $date_formatted = date("jS F Y", mktime(0, 0, 0, $_month, $_day, $_year));
                 $xml->addChild('timestamp', $timestamp);
                 $xml->addChild('date_formatted', $date_formatted);
                 $xml->addChild('name_solo', $name_solo);
                 $xml->addChild('package', $package_type);
                 $xml->addChild('css_class', $_key);
                 $themes[$_key] = $xml;
                 // Add the themes to a local array for working with in this class.
                 $this->themes[$_key] = $xml;
             }
             // End FOREACH Loop
         }
         // End IF Statement
         // Add the themes to a local array for working with in this class.
         // $this->themes = $themes;
         return $themes;
     }
     // End IF Statement
 }
Example #5
0
 private function setShardKey(ClassMetadataInfo $class, \SimpleXmlElement $xmlShardkey)
 {
     $attributes = $xmlShardkey->attributes();
     $keys = array();
     $options = array();
     foreach ($xmlShardkey->{'key'} as $key) {
         $keys[(string) $key['name']] = isset($key['order']) ? (string) $key['order'] : 'asc';
     }
     if (isset($attributes['unique'])) {
         $options['unique'] = 'true' === (string) $attributes['unique'];
     }
     if (isset($attributes['numInitialChunks'])) {
         $options['numInitialChunks'] = (int) $attributes['numInitialChunks'];
     }
     if (isset($xmlShardkey->{'option'})) {
         foreach ($xmlShardkey->{'option'} as $option) {
             $value = (string) $option['value'];
             if ($value === 'true') {
                 $value = true;
             } elseif ($value === 'false') {
                 $value = false;
             } elseif (is_numeric($value)) {
                 $value = preg_match('/^[-]?\\d+$/', $value) ? (int) $value : (double) $value;
             }
             $options[(string) $option['name']] = $value;
         }
     }
     $class->setShardKey($keys, $options);
 }
Example #6
0
 /**
  * Treats a <data type="param:..."> node and its children:
  * Count of related records in other table.
  *
  * @access private
  * @param  SimpleXmlElement  $data
  * @return string
  */
 protected function process_param($data)
 {
     $cnt_name = $data->attributes('name');
     $cnt_val = $data->attributes('value');
     $cnt_valtype = $data->attributes('valuetype');
     $formula = $this->sqlCleanQuote($cnt_val, $cnt_valtype);
     if ($cnt_name) {
         $formula .= ' AS `' . $cnt_name . '`';
     }
     return $formula;
 }
 /**
  * given a single ->data or ->struct element, return an array containing its contents as old toolkit-style data description.
  *
  * @param \SimpleXmlElement $dataElement
  * @return array
  */
 public function singlePcmlToArray(\SimpleXmlElement $dataElement)
 {
     $tagName = $dataElement->getName();
     // get attributes of this element.
     $attrs = $dataElement->attributes();
     // both struct and data have name, count (optional), usage
     $name = isset($attrs['name']) ? (string) $attrs['name'] : '';
     $count = isset($attrs['count']) ? (string) $attrs['count'] : '';
     $usage = isset($attrs['usage']) ? (string) $attrs['usage'] : '';
     $structName = isset($attrs['struct']) ? (string) $attrs['struct'] : '';
     // fill this if we have a struct
     $subElements = array();
     // should all be data
     if ($tagName == 'data') {
         $type = isset($attrs['type']) ? (string) $attrs['type'] : '';
         // if a struct then we need to recurse.
         if ($type != 'struct') {
             // regular type (char, int...), not a struct, so the data element's name is just 'name'.
             $nameName = 'Name';
         } else {
             // it IS a struct.
             // old toolkit uses DSName for a data structure's name.
             $nameName = 'DSName';
             $theStruct = null;
             // init
             // look for matching struct
             if ($this->_pcmlStructs) {
                 // TODO verify type with is_array and count
                 foreach ($this->_pcmlStructs as $possibleStruct) {
                     $possStructAttrs = $possibleStruct->attributes();
                     if ($possStructAttrs['name'] == $structName) {
                         $theStruct = $possibleStruct;
                         $structAttrs = $possStructAttrs;
                         break;
                     }
                 }
             }
             // if struct was not found, generate error for log
             if (!$theStruct) {
                 //                    $this->getConnection->logThis("PCML structure '$structName' not found.");
                 return null;
             }
             // if we got here, we found our struct.
             // count can also be defined at the structure level. If so, it will override count from data level)
             if (isset($structAttrs['count'])) {
                 $count = (string) $structAttrs['count'];
             }
             // "usage" (in/out/inherit) can be defined here, at the structure level.
             $structUsage = isset($structAttrs['usage']) ? (string) $structAttrs['usage'] : '';
             // if we're not inheriting from our parent data element, but there is a struct usage, use the struct's usage (input, output, or inputoutput).
             if (!empty($structUsage) && $structUsage != 'inherit') {
                 $usage = $structUsage;
             }
             $structSubDataElementsXmlObj = $theStruct->xpath('data');
             if ($structSubDataElementsXmlObj) {
                 foreach ($structSubDataElementsXmlObj as $subDataElementXmlObj) {
                     if ($subDataElementXmlObj->attributes()->usage == 'inherit') {
                         // subdata is inheriting type from us. Give it to them.
                         $subDataElementXmlObj->attributes()->usage = $usage;
                     }
                     // here's where the recursion comes in. Convert data and add to array for our struct.
                     $subElements[] = $this->singlePcmlToArray($subDataElementXmlObj);
                 }
             }
         }
         $length = isset($attrs['length']) ? (string) $attrs['length'] : '';
         $precision = isset($attrs['precision']) ? (string) $attrs['precision'] : '';
         //$struct = (isset($attrs['struct'])) ? (string) $attrs['struct'] : ''; // if this is pointing to a struct name
         // find CW data type equivalent of PCML data type
         if (isset($this->_pcmlTypeMap[$type])) {
             // a simple type mapping
             $newType = (string) $this->_pcmlTypeMap[$type];
         } elseif ($type == 'int') {
             // one of the integer types. Need to use length to determine which one.
             if ($length == '2') {
                 $newType = I5_TYPE_SHORT;
             } elseif ($length == '4') {
                 $newType = I5_TYPE_INT;
             } else {
                 $newType = '';
                 // no match
             }
         } else {
             $newtype = '';
         }
         $newInout = isset($this->_pcmlInoutMap[$usage]) ? (string) $this->_pcmlInoutMap[$usage] : '';
         // create new length using precision if necessary
         if ($precision) {
             $newLength = "{$length}.{$precision}";
         } else {
             $newLength = $length;
         }
     }
     // count
     $newCount = 0;
     // initialize
     $newCountRef = '';
     if (is_numeric($count) && $count > 0) {
         $newCount = $count;
     } elseif (is_string($count) && !empty($count)) {
         // count is character, so it's really a countref
         $newCountRef = $count;
     }
     $element = array();
     $element[$nameName] = $name;
     // if not a struct, provide data type.
     if ($type != 'struct') {
         $element['Type'] = $newType;
     }
     if ($newCount) {
         $element['Count'] = $newCount;
     }
     if ($newCountRef) {
         $element['CountRef'] = $newCountRef;
     }
     if ($newLength) {
         $element['Length'] = $newLength;
     }
     if ($newInout) {
         $element['IO'] = $newInout;
     }
     if (count($subElements)) {
         $element['DSParm'] = $subElements;
     }
     return $element;
 }
Example #8
0
 private function addIndex(ClassMetadataInfo $class, \SimpleXmlElement $xmlIndex)
 {
     $attributes = $xmlIndex->attributes();
     $keys = array();
     foreach ($xmlIndex->{'key'} as $key) {
         $keys[(string) $key['name']] = isset($key['order']) ? (string) $key['order'] : 'asc';
     }
     $options = array();
     if (isset($attributes['background'])) {
         $options['background'] = 'true' === (string) $attributes['background'];
     }
     if (isset($attributes['drop-dups'])) {
         $options['dropDups'] = 'true' === (string) $attributes['drop-dups'];
     }
     if (isset($attributes['name'])) {
         $options['name'] = (string) $attributes['name'];
     }
     if (isset($attributes['safe'])) {
         $options['safe'] = 'true' === (string) $attributes['safe'];
     }
     if (isset($attributes['sparse'])) {
         $options['sparse'] = 'true' === (string) $attributes['sparse'];
     }
     if (isset($attributes['unique'])) {
         $options['unique'] = 'true' === (string) $attributes['unique'];
     }
     if (isset($xmlIndex->{'option'})) {
         foreach ($xmlIndex->{'option'} as $option) {
             $value = (string) $option['value'];
             if ($value === 'true') {
                 $value = true;
             } elseif ($value === 'false') {
                 $value = false;
             } elseif (is_numeric($value)) {
                 $value = preg_match('/^[-]?\\d+$/', $value) ? (int) $value : (double) $value;
             }
             $options[(string) $option['name']] = $value;
         }
     }
     $class->addIndex($keys, $options);
 }
Example #9
0
 /**
  * does attribute exist under a specific node
  * As we are supporting namespaces the only way to get to the attributes under a node is to use attributes function on it
  *
  * @param SimpleXMLElement $node
  * @param  $attributeName
  * @return string
  */
 protected function _isAttributeSet(SimpleXmlElement $node, $attributeName)
 {
     $attributes = $node->attributes();
     return isset($attributes[$attributeName]);
 }
Example #10
0
 /**
  * @param string $query
  */
 private function executeQuery($query)
 {
     if (null !== $this->getLocale()) {
         // Supported 2- character values are de, en, es, fr, it, nl, pl, pt, and sv.
         // Equivalent 3-character values are GER, ENG, SPA, FRE, ITA, DUT, POL, POR, and SWE.
         $query = sprintf('%s&language=%s', $query, substr($this->getLocale(), 0, 2));
     }
     $request = $this->getMessageFactory()->createRequest('GET', $query);
     $content = (string) $this->getHttpClient()->sendRequest($request)->getBody();
     if (false !== stripos($content, "Developer Inactive")) {
         throw new InvalidCredentials('Map API Key provided is not valid.');
     }
     try {
         $xml = new \SimpleXmlElement($content);
     } catch (\Exception $e) {
         throw new NoResult(sprintf('Could not execute query "%s".', $query));
     }
     $attributes = $xml->attributes();
     if (isset($attributes['count']) && 0 === (int) $attributes['count']) {
         throw new NoResult(sprintf('Could not execute query "%s".', $query));
     }
     if (isset($attributes['errorCode'])) {
         if ('403' === (string) $attributes['errorCode']) {
             throw new InvalidCredentials('Map API Key provided is not valid.');
         }
         throw new NoResult(sprintf('Could not execute query "%s".', $query));
     }
     $data = isset($xml->geoResult) ? $xml->geoResult : $xml->reverseGeoResult;
     if (0 === count($data)) {
         return $this->returnResults([$this->getResultArray($data)]);
     }
     $results = [];
     foreach ($data as $item) {
         $results[] = $this->getResultArray($item);
     }
     return $this->returnResults($results);
 }
 /**
  * @param string $query
  *
  * @return array
  */
 protected function executeQuery($query)
 {
     if (null !== $this->getLocale()) {
         // Supported 2- character values are de, en, es, fr, it, nl, pl, pt, and sv.
         // Equivalent 3-character values are GER, ENG, SPA, FRE, ITA, DUT, POL, POR, and SWE.
         $query = sprintf('%s&language=%s', $query, substr($this->getLocale(), 0, 2));
     }
     $content = $this->getAdapter()->getContent($query);
     try {
         $xml = new \SimpleXmlElement($content);
     } catch (\Exception $e) {
         throw new NoResultException(sprintf('Could not execute query %s', $query));
     }
     $attributes = $xml->attributes();
     if (isset($attributes['count']) && 0 === (int) $attributes['count']) {
         throw new NoResultException(sprintf('Could not execute query %s', $query));
     }
     if (isset($attributes['errorCode'])) {
         if ('403' === (string) $attributes['errorCode']) {
             throw new InvalidCredentialsException('Map API Key provided is not valid.');
         }
         throw new NoResultException(sprintf('Could not execute query %s', $query));
     }
     $data = isset($xml->geoResult) ? $xml->geoResult : $xml->reverseGeoResult;
     if (0 === count($data)) {
         return array($this->getResultArray($data));
     }
     $results = array();
     foreach ($data as $item) {
         $results[] = $this->getResultArray($item);
     }
     return $results;
 }
Example #12
0
 /**
  * Tests getting element attributes
  * @covers \Copycat\Structure\SimpleXmlElement::attributes()
  */
 public function testAttributes()
 {
     $element = new SimpleXmlElement('<Test foo="bar"></Test>');
     $this->assertInstanceOf('\\Copycat\\Structure\\SimpleXmlElement', $element->attributes());
 }
Example #13
0
 /**
  * Return array of founded attributes of given $node.
  * @param  SimpleXmlElement $node Node to retrive attributes from.
  * @return array
  */
 public function getAttributes($node)
 {
     $attributes = [];
     foreach ($node->attributes() as $name => $value) {
         $attributes[$name] = $value;
     }
     return $attributes;
 }
Example #14
0
 private function addIndex(ClassMetadataInfo $class, \SimpleXmlElement $xmlIndex)
 {
     $attributes = $xmlIndex->attributes();
     $keys = array();
     foreach ($xmlIndex->{'key'} as $key) {
         $keys[(string) $key['name']] = isset($key['order']) ? (string) $key['order'] : 'asc';
     }
     $options = array();
     if (isset($attributes['background'])) {
         $options['background'] = 'true' === (string) $attributes['background'];
     }
     if (isset($attributes['drop-dups'])) {
         $options['dropDups'] = 'true' === (string) $attributes['drop-dups'];
     }
     if (isset($attributes['name'])) {
         $options['name'] = (string) $attributes['name'];
     }
     if (isset($attributes['safe'])) {
         $options['safe'] = 'true' === (string) $attributes['safe'];
     }
     if (isset($attributes['sparse'])) {
         $options['sparse'] = 'true' === (string) $attributes['sparse'];
     }
     if (isset($attributes['unique'])) {
         $options['unique'] = 'true' === (string) $attributes['unique'];
     }
     if (isset($xmlIndex->{'option'})) {
         foreach ($xmlIndex->{'option'} as $option) {
             $value = (string) $option['value'];
             if ($value === 'true') {
                 $value = true;
             } elseif ($value === 'false') {
                 $value = false;
             } elseif (is_numeric($value)) {
                 $value = preg_match('/^[-]?\\d+$/', $value) ? (int) $value : (double) $value;
             }
             $options[(string) $option['name']] = $value;
         }
     }
     if (isset($xmlIndex->{'partial-filter-expression'})) {
         $partialFilterExpressionMapping = $xmlIndex->{'partial-filter-expression'};
         if (isset($partialFilterExpressionMapping->and)) {
             foreach ($partialFilterExpressionMapping->and as $and) {
                 if (!isset($and->field)) {
                     continue;
                 }
                 $partialFilterExpression = $this->getPartialFilterExpression($and->field);
                 if (!$partialFilterExpression) {
                     continue;
                 }
                 $options['partialFilterExpression']['$and'][] = $partialFilterExpression;
             }
         } elseif (isset($partialFilterExpressionMapping->field)) {
             $partialFilterExpression = $this->getPartialFilterExpression($partialFilterExpressionMapping->field);
             if ($partialFilterExpression) {
                 $options['partialFilterExpression'] = $partialFilterExpression;
             }
         }
     }
     $class->addIndex($keys, $options);
 }
Example #15
0
/**
 * Get the old_content_id array of content and fetch new content id .
 *
 * @param integer $courseid the course id in which the class is scheduled.
 * @param array $clist_array the old_content_id of old content uploaded by soap api.
 */
function wiziq_get_contentid_update($courseid, $clist_array) {
    global $CFG, $USER, $DB, $wiziq_secretacesskey, $wiziq_access_key, $wiziq_content_webservice;
    require_once("authbase.php");
    $wiziq_access_key= $CFG->wiziq_access_key;
    $wiziq_secretacesskey = $CFG->wiziq_secretacesskey;
    $wiziq_content_webservice = $CFG->wiziq_content_webservice;
    $context = context_course::instance($courseid);
    require_once("authbase.php");
    $wiziq_authbase = new wiziq_authbase($wiziq_secretacesskey, $wiziq_access_key);
    $method = "listContentIds";
    $requestparameters["signature"] = $wiziq_authbase->wiziq_generatesignature($method,
                                                                               $requestparameters);
    $clist_list = implode(',', $clist_array);
    $requestparameters["page_size"] = WIZIQ_DEFAULT_PAGESIZE;
    $requestparameters["multiple_content_id"] = $clist_list;
    $wiziq_httprequest=new wiziq_httprequest();
    try {
        $xmlreturn=$wiziq_httprequest->wiziq_do_post_request(
                                                $wiziq_content_webservice.'?method=listContentIds',
                                                $requestparameters);
        libxml_use_internal_errors(true);
        $xmldata = new SimpleXmlElement($xmlreturn, LIBXML_NOCDATA);
        $attribnode = (string)$xmldata->attributes();
        if ($attribnode=="ok") {
            $get_data = $xmldata->listContentIds->record_list;
            foreach ($get_data->record as $record) {
                $content_id = (string)$record->content_id;
                $wzq_content_id = (string)$record->wzq_content_id;
                $content_ids[$content_id] = $wzq_content_id;
            }
            foreach ($clist_array as $key => $value) {
                /*
                 * we use isset for performance knowing the the
                 * value for particular key will never be null
                 */
                if (isset($content_ids[$value])) {
                    $updates = new stdClass(); //just enough data for updating the submission
                    $updates->id = $key;
                    $updates->contentid = $content_ids[$value];
                    $updates->cid_change_status = '1';
                    $DB->update_record('wiziq_content', $updates);
                }
            }
        } else if ($attribnode=="fail") {
            $att = 'msg';
            $code = 'code';
            $error_code = (string)$xmldata->error->attributes()->$code;
            $error_msg = (string)$xmldata->error->attributes()->$att;
            $paramslog = array(
                    'objectid' => $courseid,
                    'relateduserid' => $USER->id,
                    'courseid' => $courseid,
                    'context' => $context,
                    'other' => array(
                        'sesskey' => sesskey(),
                        'error' => $errormsg
                    )
            );
            $event = \mod_wiziq\event\wiziq_content::create($paramslog);
            $event->trigger();
            $error = $error_code." ".$error_msg;
            print_error('1', '', '', $error);

        }
    } catch (Exception $e) {
        if (property_exists($e, 'errorcode')) {
            notify($e->a);
        } else {
            $errormsg = get_string('errorinservice', 'wiziq');
            notify($e->getMessage().'<br />'.$errormsg);
        }
    }
}
Example #16
0
 /**
  * given a single ->data or ->struct element, return a parameter object in the new toolkit style.
  * 
  * @todo this needs more validation. It is possible that all parts are not set to create return
  * 
  * @param \SimpleXmlElement $dataElement
  * @return ProgramParameter
  */
 public function singlePcmlToParam(\SimpleXmlElement $dataElement)
 {
     $tagName = $dataElement->getName();
     // get attributes of this element.
     $attrs = $dataElement->attributes();
     // both struct and data have name, count (optional), usage
     $name = isset($attrs['name']) ? (string) $attrs['name'] : '';
     $count = isset($attrs['count']) ? (string) $attrs['count'] : '';
     $usage = isset($attrs['usage']) ? (string) $attrs['usage'] : '';
     $structName = isset($attrs['struct']) ? (string) $attrs['struct'] : '';
     // fill this if we have a struct
     $subElements = array();
     // each item should have tag name <data>
     if ($tagName != 'data') {
         return false;
     }
     $type = isset($attrs['type']) ? (string) $attrs['type'] : '';
     // Get initial value, if specified by PCML.
     $dataValue = isset($attrs['init']) ? (string) $attrs['init'] : '';
     // if a struct then we need to recurse.
     if ($type == 'struct') {
         $theStruct = null;
         // init
         // look for matching struct definition encountered earlier.
         if ($this->_pcmlStructs) {
             // @todo verify type with is_array and count
             foreach ($this->_pcmlStructs as $possibleStruct) {
                 $possStructAttrs = $possibleStruct->attributes();
                 if ($possStructAttrs['name'] == $structName) {
                     $theStruct = $possibleStruct;
                     $structAttrs = $possStructAttrs;
                     break;
                 }
             }
         }
         // if struct was not found, generate error for log
         if (!$theStruct) {
             // $this->getConnection->logThis("PCML structure '$structName' not found.");
             return null;
         }
         // count can also be defined at the structure level. If so, it will override count from data level)
         if (isset($structAttrs['count'])) {
             $count = (string) $structAttrs['count'];
         }
         // "usage" (in/out/inherit) can be defined here, at the structure level.
         $structUsage = isset($structAttrs['usage']) ? (string) $structAttrs['usage'] : '';
         // if we're not inheriting from our parent data element, but there is a struct usage, use the struct's usage (input, output, or inputoutput).
         if (!empty($structUsage) && $structUsage != 'inherit') {
             $usage = $structUsage;
         }
         $structSubDataElementsXmlObj = $theStruct->xpath('data');
         if ($structSubDataElementsXmlObj) {
             foreach ($structSubDataElementsXmlObj as $subDataElementXmlObj) {
                 if ($subDataElementXmlObj->attributes()->usage == 'inherit') {
                     // subdata is inheriting type from us. Give it to them.
                     $subDataElementXmlObj->attributes()->usage = $usage;
                 }
                 // here's where the recursion comes in. Convert data and add to array for our struct.
                 $subElements[] = $this->singlePcmlToParam($subDataElementXmlObj);
             }
         }
     }
     /* explanation of the terms "length" and "precision" in PCML:
      * http://publib.boulder.ibm.com/infocenter/iadthelp/v6r0/index.jsp?topic=/com.ibm.etools.iseries.webtools.doc/ref/rdtcattr.htm
      * 
      * For "int" values, length is the number of bytes; precision represents the number of bits. (Can be ignored here)
      * For zoned and packed values, length is the maximum number of digits; precision represents the maximum decimal places.
      * 
      */
     $length = isset($attrs['length']) ? (string) $attrs['length'] : '';
     $precision = isset($attrs['precision']) ? (string) $attrs['precision'] : '';
     $passBy = '';
     // default of blank will become 'ref'/Reference in XMLSERVICE. Blank is fine here.
     if (isset($attrs['passby']) && $attrs['passby'] == 'value') {
         $passBy = 'val';
         // rare. PCML calls it 'value'. XMLSERVICE calls it 'val'.
     }
     // find new toolkit equivalent of PCML data type
     if (isset($this->_pcmlTypeMap[$type])) {
         // a simple type mapping
         $newType = (string) $this->_pcmlTypeMap[$type];
     } elseif ($type == 'int') {
         // one of the integer types. Need to use length to determine which one.
         if ($length == '2') {
             $newType = '5i0';
             // short ints have two bytes
         } elseif ($length == '4') {
             $newType = '10i0';
             // normal ints have four bytes
         } else {
             $newType = '';
             // no match
         }
         //(length == 2, et al.)
     } else {
         $newType = '';
     }
     $newInout = isset($this->_pcmlInoutMap[$usage]) ? (string) $this->_pcmlInoutMap[$usage] : '';
     // @todo correct all this isArray business.
     // Can we manage without isArray?
     // well, it's already handled by toolkit....try and see, though.
     // poss. eliminate extra object levels, at least?
     if ($count > 1) {
         $isArray = true;
     } else {
         // no need for any dummy value.Could be 'init' from above, or leave the default.
         $isArray = false;
     }
     // @todo I think simply add 'counterLabel' and 'countedLabel'.
     // count
     $newCount = 0;
     // initialize
     // @todo deal with this. Really need a better way to find the counter data elements.
     // Allow a countref, too, in PCML??? Maybe! Count will be the dim (max) and countref is the actual name.
     // Some customers have done it wrong. Instead of specifying a field as count, gave max count.
     // "count can be a number where number defines a fixed, never-changing number of elements in a sized array.
     // OR a data-name where data-name defines the name of a <data> element within the PCML document that will contain, at runtime, the number of elements in the array. The data-name specified can be a fully qualified name or a name that is relative to the current element. In either case, the name must reference a <data> element that is defined with type="int". See Resolving Relative Names for more information about how relative names are resolved.
     // about finding the element: http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frzahh%2Flengthprecisionrelative.htm
     // Names are resolved by seeing if the name can be resolved as a child or descendent of the tag containing the current tag. If the name cannot be resolved at this level, the search continues with the next highest containing tag. This resolution must eventually result in a match of a tag that is contained by either the <pcml> tag or the <rfml> tag, in which case the name is considered to be an absolute name, not a relative name.""
     // Let's simply use $countersAndCounted. If necessary, pre-process PCML to create $countersAndCounted.
     if (is_numeric($count) && $count > 0) {
         $newCount = $count;
     }
     // $subElements are if this is a struct.
     if (count($subElements)) {
         $dataValue = $subElements;
     }
     $param = new ProgramParameter(sprintf($newType, $length, $precision), $newInout, '', $name, $dataValue, 'off', $newCount, $passBy, $isArray);
     if ($this->_countersAndCounted) {
         // some counters were configured
         // counter item reference was specified.
         if (isset($this->_countersAndCounted[$name])) {
             $param->setParamLabelCounter($name);
         }
         // counted item reference was specified as value in array.
         // look for value ($name). if found, counter is key.
         if ($counter = array_search($name, $this->_countersAndCounted)) {
             $param->setParamLabelCounted($counter);
         }
     }
     return $param;
 }