@param $xmlParser
@param $tagName
@param $attributes

@throws RequiredAttributeException
482843
private function openTagHandler($xmlParser, $tagName, $attributes) {
		if($this->firstOpening) {
			$this->firstOpening = false;

			//Position the namespace:
			$matches = null;
			foreach($attributes as $attrName => $attrValue) {
				if(preg_match('/figdice/', $attrValue) &&
					 preg_match('/xmlns:(.+)/', $attrName, $matches)) {
					$this->figNamespace = $matches[1] . ':';
					break;
				}
			}

            // Remove the fig xmlns directive from the list of attributes of the opening root tag
            // (as it should not be rendered)
            unset($attributes['xmlns:' . substr($this->figNamespace, 0, strlen($this->figNamespace) - 1)]);

			// Consume optional fig:trans directive
            if (isset($attributes[$this->figNamespace.'trans'])) {
                $this->defaultTransSource = $attributes[$this->figNamespace.'trans'];
                // Remove the attribute from the list of attributes of the opening root tag
                unset($attributes[$this->figNamespace.'trans']);
            }
        }

		$lineNumber = xml_get_current_line_number($xmlParser);


		//
		// Detect special tags
        //
		if($tagName == $this->figNamespace . TagFigAttr::TAGNAME) {
			$newElement = new TagFigAttr($tagName, $lineNumber);
		} else if ($tagName == $this->figNamespace . TagFigCdata::TAGNAME) {
            $newElement = new TagFigCdata($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigDictionary::TAGNAME) {
            $newElement = new TagFigDictionary($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigFeed::TAGNAME) {
		    $newElement = new TagFigFeed($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigInclude::TAGNAME) {
		    $newElement = new TagFigInclude($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigMount::TAGNAME) {
		    $newElement = new TagFigMount($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigParam::TAGNAME) {
		    $newElement = new TagFigParam($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigTrans::TAGNAME) {
		    $newElement = new TagFigTrans($tagName, $lineNumber);
        } else if ($tagName == $this->figNamespace . TagFigVal::TAGNAME) {
		    $newElement = new TagFigVal($tagName, $lineNumber);
        } else {
			$newElement = new ViewElementTag($tagName, $lineNumber, $this->previousCData);
		}

		$this->previousCData = null;

		$newElement->setAttributes($this->figNamespace, $attributes);


		if($this->rootNode) {
            /** @var ViewElementTag $parentElement */
			$parentElement = & $this->stack[count($this->stack)-1];
			$newElement->parent = &$parentElement;

			//Since the new element has a parent, then the parent is not autoclose.
			$newElement->parent->autoclose = false;

			$parentElement->appendChild($newElement);
		} else
		{
			//If there no root node yet, then this new element is actually
			//the root element for the view.
			$this->rootNode = &$newElement;
		}

		$this->stack[] = & $newElement;
	}
783229
public void setAttribute(TagLibTagAttr attribute) {
	attributes.put(attribute.getName(), attribute);
	if (attrFirst == null) attrFirst = attribute;
	attrLast = attribute;
    }
992841
function StartElement($parser, $name, $attrs = array())
    {
        //Make the name of the tag lower case
        $name = strtolower($name);
        
        //Check to see if tag is root-level
        if (count($this->stack) == 0) 
        {
            //If so, set the document as the current tag
            $this->document = new MultiotpXMLTag($name, $attrs);

            //And start out the stack with the document tag
            $this->stack = array('document');
        }
        //If it isn't root level, use the stack to find the parent
        else
        {
            //Get the name which points to the current direct parent, relative to $this
            $parent = $this->GetStackLocation();
            
            //Add the child
            eval('$this->'.$parent.'->AddChild($name, $attrs, '.count($this->stack).', $this->cleanTagNames);');
            
            //If the cleanTagName feature is on, replace colons and dashes with underscores
            if($this->cleanTagNames)
                $name = str_replace(array(':', '-'), '_', $name);


            //Update the stack
            eval('$this->stack[] = $name.\'[\'.(count($this->'.$parent.'->'.$name.') - 1).\']\';');
        }
    }
1330454
protected function handleTagOpenForArray( $parser, $tag, $attributes )
	{
		$count	= count( $this->last ) - 1;
		$this->last[$count][]	= array(
			"tag"			=> $tag,
			"attributes"	=> $attributes,
			"content"		=> '',
			"children"		=> array()
		);
		$index	= count( $this->last[$count] ) - 1;
		$this->last[]	= &$this->last[$count][$index]['children'];
	}
381350
private function validateUserInputs($attributes, $eventTags = null)
    {
        if (!is_null($attributes) && !Validator::areAttributesValid($attributes)) {
            $this->_logger->log(Logger::ERROR, 'Provided attributes are in an invalid format.');
            $this->_errorHandler->handleError(
                new InvalidAttributeException('Provided attributes are in an invalid format.')
            );
            return false;
        }

        if (!is_null($eventTags)) {
            if (!Validator::areEventTagsValid($eventTags)) {
                $this->_logger->log(Logger::ERROR, 'Provided event tags are in an invalid format.');
                $this->_errorHandler->handleError(
                    new InvalidEventTagException('Provided event tags are in an invalid format.')
                );
                return false;
            }
        }

        return true;
    }
483540
public function setAttributes($figNamespace, array $attributes)
    {
        // We don't call the parent version, which does extraneous work of resolving conds and walks etc.,
        // whereas we just need to check existence of class attribute.
        // A feed tag is oblivious to other control directives.

        $this->attributes = $attributes;

        $this->dicFile = $this->getAttribute('file', null);
        $this->dicName = $this->getAttribute('name', null);
        $this->source = $this->getAttribute('source', null);

        unset($this->attributes['file']);
        unset($this->attributes['name']);
        unset($this->attributes['source']);


        if(null === $this->dicFile) {
            throw new RequiredAttributeException($this->getTagName(),
                $this->xmlLineNumber,
                'file');
        }

    }
1055805
public function dontSeeElementInDOM($selector, $attributes = [])
    {
        $els = $this->match($this->getBaseElement(), $selector);
        $els = $this->filterByAttributes($els, $attributes);
        $this->assertEmpty($els);
    }
1082071
public static function createElement($tag = '', $attributes1 = [], $attributes2 = [])
    {
        $tag_object = parent::createElement($tag);
        $tag_object->setTag($tag);
        $attributes = $attributes1;
        if (!is_array($attributes1) && strlen($attributes1) > 0) {
            $tag_object->text($attributes1);
            $attributes = $attributes2;
        }
        if (is_array($attributes)) {
            foreach ($attributes as $name => $value) {
                if (method_exists($tag_object, $name)) {
                    if (!is_array($value)) {
                        $value = [$value];
                    }
                    call_user_func_array([$tag_object, $name], $value);
                }
            }
        }

        $tag_object->configDefaults($tag);

        return $tag_object;
    }
206231
protected function extendedAttrRequired(DOMNode $node, DOMAttr $attr)
	{
		$id = $node->getAttribute('id');

		$message = $attr->value;
		$this->js []= "addValidator('required', '#$id', '$message');";

	}
52393
public static function getCustomAttribute( $tag, $attributeName )
    {
        foreach ( $tag->attributes as $attribute )
        {
            if ( $attribute->name === $attributeName
              && $attribute->namespaceURI === 'http://ez.no/namespaces/ezpublish3/custom/' )
            {
                return $attribute->value;
            }
        }
        return null;
    }
950780
def required_attributes(element, *attributes):
    
    if not reduce(lambda still_valid, param: still_valid and param in element.attrib, attributes, True):
        raise NotValidXmlException(msg_err_missing_attributes(element.tag, *attributes))
385993
public function writeElement(
            string $elementName,
            array $attributes = [],
            string $cdata     = null
    ): XmlStreamWriter {
        $this->writeStartElement($elementName);
        foreach ($attributes as $attName => $attValue) {
            $this->writeAttribute($attName, $attValue);
        }

        if (null !== $cdata) {
            $this->writeText($cdata);
        }

        $this->writeEndElement();
        return $this;
    }
893124
function outputTag( $element, &$siblingParams, $parentParams = array() )
    {
        $tagName = $element->localName;
        if ( isset( $this->OutputTags[$tagName] ) )
        {
            $currentTag = $this->OutputTags[$tagName];
        }
        else
        {
            $currentTag = null;
        }

        // Prepare attributes array
        $attributes = array();
        if ( $element->hasAttributes() )
        {
            $attributeNodes = $element->attributes;

            foreach ( $attributeNodes as $attrNode )
            {
                if ( $attrNode->prefix && $attrNode->prefix != 'custom' )
                {
                    $attrName = $attrNode->prefix . ':' . $attrNode->localName;
                }
                else
                {
                    $attrName = $attrNode->nodeName;
                }

                // classes check
                if ( $attrName == 'class' )
                {
                    $classesList = $this->XMLSchema->getClassesList( $tagName );
                    if ( !in_array( $attrNode->value, $classesList ) )
                    {
                        eZDebug::writeWarning( "Using tag '$tagName' with class '$attrNode->value' is not allowed.", 'XML output handler' );
                        return array( true, '' );
                    }
                }

                $attributes[$attrName] = $attrNode->value;
            }
        }

        // Set default attribute values if not present in the input
        $attrDefaults = $this->XMLSchema->attrDefaultValues( $tagName );
        foreach ( $attrDefaults as $name=>$value )
        {
            if ( !isset( $attributes[$name] ) )
            {
                $attributes[$name] = $value;
            }
        }

        // Init handler returns an array that may contain the following items:
        //
        // 'no_render'       (boolean) :
        //                   If false tag will not be rendered, only it's children (if any).
        // 'design_keys'     array( 'design_key_name_1' => 'value_1', 'design_key_name_2'=>'value_2', ... ) :
        //                   An array of additional design keys.
        // 'tpl_vars'        array( 'var_name_1' => 'value_1', 'var_name_2' => 'value_2', ... ) :
        //                   An array of additional template variables.
        // 'template_name'   (string) :
        //                   Overrides tag template name.

        $result = $this->callTagInitHandler( 'initHandler', $element, $attributes, $siblingParams, $parentParams );

        // Process children
        $childrenOutput = array();
        if ( $element->hasChildNodes() )
        {
            // Initialize sibiling parameters array for the next level children
            // Parent parameters for the children may be modified in the current tag handler.
            $nextSibilingParams = array();

            $this->NestingLevel++;
            foreach( $element->childNodes as $child )
            {
                $childOutput = $this->outputTag( $child, $nextSibilingParams, $parentParams );

                if ( is_array( $childOutput[0] ) )
                {
                    $childrenOutput = array_merge( $childrenOutput, $childOutput );
                }
                else
                {
                    $childrenOutput[] = $childOutput;
                }
            }
            $this->NestingLevel--;
        }
        else
        {
            $childrenOutput = array( array( true, '' ) );
        }

        if ( isset( $result['no_render'] ) && $result['no_render'] )
        {
            return $childrenOutput;
        }

        // Set tpl variables by attributes and rename rules
        $vars = array();

        if ( !isset( $currentTag['quickRender'] ) && isset( $currentTag['attrNamesTemplate'] ) )
        {
            $attrRenameRules = $currentTag['attrNamesTemplate'];
        }
        elseif ( isset( $currentTag['quickRender'] ) && isset( $currentTag['attrNamesQuick'] ) )
        {
            $attrRenameRules = $currentTag['attrNamesQuick'];
        }
        else
        {
            $attrRenameRules = array();
        }

        foreach( $attributes as $name=>$value )
        {
            if ( isset( $attrRenameRules[$name] ) )
            {
                $vars[$attrRenameRules[$name]] = $value;
                continue;
            }

            if ( strpos( $name, 'custom:' ) === 0 )
            {
                $name = substr( $name, 7 );
            }

            $vars[$name] = $value;
        }

        // set missing variables that have rename rules defined
        // but were not present in the element
        foreach( $attrRenameRules as $attrName=>$varName )
        {
            if ( !isset( $attributes[$attrName] ) )
            {
                $vars[$varName] = '';
            }
        }

        $this->TemplateUri = '';

        // In quick render mode we does not use templates and
        // render template variables as tag attributes
        if ( !isset( $currentTag['quickRender'] ) )
        {
            // Set additional variables passed by tag handler
            if ( isset( $result['tpl_vars'] ) )
            {
                $vars = array_merge( $vars, $result['tpl_vars'] );
            }

            foreach( $vars as $name=>$value )
            {
                $this->Tpl->setVariable( $name, $value, 'xmltagns' );
            }

            // Create design keys array (including the ones with no value so they still overwrite values of parent tag)
            $designKeys = array();
            if ( isset( $currentTag['attrDesignKeys'] ) )
            {
                foreach( $currentTag['attrDesignKeys'] as $attrName=>$keyName )
                {
                    if ( isset( $attributes[$attrName] ) )
                    {
                        $designKeys[$keyName] = $attributes[$attrName];
                    }
                }
            }
            // Set additional design keys passed by tag handler
            if ( isset( $result['design_keys'] ) )
            {
                $designKeys = array_merge( $designKeys, $result['design_keys'] );
            }

            $existingKeys = $this->Res->keys();
            $savedKeys = array();

            // Save old keys values and set new design keys
            foreach( $designKeys as $key=>$value )
            {
                if ( isset( $existingKeys[$key] ) )
                {
                    $savedKeys[$key] = $existingKeys[$key];
                }
                $this->Res->setKeys( array( array( $key, $value ) ) );
            }

            // Template name
            if ( isset( $result['template_name'] ) )
            {
                $templateName = $result['template_name'];
            }
            else
            {
                $templateName = $element->nodeName;
            }
            $this->TemplateUri = $this->TemplatesPath . $templateName . '.tpl';
        }

        $output = $this->callTagRenderHandler( 'renderHandler', $element, $childrenOutput, $vars );

        if ( !isset( $currentTag['quickRender'] ) )
        {
            // Restore saved template override keys and remove others
            foreach( $designKeys as $key => $value )
            {
                if ( isset( $savedKeys[$key] ) )
                {
                    $this->Res->setKeys( array( array( $key, $savedKeys[$key] ) ) );
                }
                else
                {
                    $this->Res->removeKey( $key );
                }
            }

            // Unset variables
            foreach ( $vars as $name=>$value )
            {
                if ( $this->Tpl->hasVariable( $name, 'xmltagns' ) )
                {
                    $this->Tpl->unsetVariable( $name, 'xmltagns' );
                }
            }
        }

        $this->callTagInitHandler( 'leavingHandler', $element, $attributes, $siblingParams, $parentParams );

        return $output;
    }
179894
public void startElement(String elemName, Attributes attrs) {
        writeStartElement(elemName, attrs);
        m_tagStack.push(elemName);
    }
962662
public void required(String tagName, String actionName, String attributeName, Object attribute) throws ApplicationException {
	if (attribute == null)
	    throw new ApplicationException("Attribute [" + attributeName + "] for tag [" + tagName + "] is required if attribute action has the value [" + actionName + "]");

    }
638479
public function startValueElement($name, $value, $attributes = array())
    {
        $this->checkStartValueElement($name);

        $this->xmlWriter->startElement($name);

        foreach ($attributes as $attributeName => $attributeValue) {
            $this->xmlWriter->startAttribute($attributeName);
            $this->xmlWriter->text($attributeValue);
            $this->xmlWriter->endAttribute();
        }

        $this->xmlWriter->text($value);
    }
643762
public function startElement($parser, $name, $attrs)
    {
        $this->blockBegin($name, $attrs);

        switch ($name) {
            case 'LI':
                $this->appendBlockText('* ');

                break;
        }
    }