<commit_before><?php
/** 
 * @package infra
 * @subpackage utils
 */

class kXsd
{
	/**
	 * @param DOMNode $from old node
	 * @param DOMNode $to new node
	 * @param string $xPath
	 * @param int $level indentation level
	 * @return bool|string true if no change required, or, xsl text if transform required
	 * @throws kXsdException
	 */
	public static function compareElement(DOMNode $from, DOMNode $to, $parentXPath = '', $level = 1)
	{
		$toName = $to->getAttribute('name');
		$fromName = $from->getAttribute('name');
		KalturaLog::debug("Compare elements [$fromName] [$toName]");
		
		$xPath = $parentXPath . "/*[local-name()='$fromName']";
						
		if($from->getAttribute('type') != $to->getAttribute('type'))
		{
			KalturaLog::debug("Elements types are different [" . $from->getAttribute('type') . "] [" . $to->getAttribute('type') . "]");
			throw new kXsdException(kXsdException::CAN_NOT_CHANGE_ELEMENT_TYPE, $from->getAttribute('type'), $to->getAttribute('type'), $xPath);
		}
			
		if($from->getAttribute('maxOccurs') > $to->getAttribute('maxOccurs'))
		{
			KalturaLog::debug("Elements max occurs reduced [" . $from->getAttribute('maxOccurs') . "] [" . $to->getAttribute('maxOccurs') . "]");
			throw new kXsdException(kXsdException::CAN_NOT_REDUCE_ELEMENT_MAX_OCCURS, $from->getAttribute('maxOccurs'), $to->getAttribute('maxOccurs'), $xPath);
		}
			
		$tabs = str_repeat("\t", $level);
		
		
		$isIdentical = true;
		
		$restriction = self::getNodeRestrictions($to, $from);
		if (strlen($restriction)){
			$isIdentical = false;
		}
		
		$xsl = self::compareNode($from, $to, $xPath, $level + 1);
		if(is_bool($xsl))
		{
			if(!$xsl)
				return false;
				
			$xsl = '<xsl:value-of select="' . $parentXPath . $restriction .'/*[local-name()=\'' . $fromName . '\']"/>';
		}
		else 
		{
			$isIdentical = false;
			$xsl = '
		' . $tabs . '<xsl:element name="' . $toName . '">' . $xsl . '
		' . $tabs . '</xsl:element>';
		}
		
		if($fromName != $toName)
		{
			$isIdentical = false;
		}
		
		if(intval($to->getAttribute('minOccurs')) && $from->getAttribute('minOccurs') < $to->getAttribute('minOccurs'))
		{
			if(!$to->hasAttribute('default'))
			{
				KalturaLog::debug("Elements min occurs increased [" . $from->getAttribute('minOccurs') . "] [" . $to->getAttribute('minOccurs') . "]");
				throw new kXsdException(kXsdException::CAN_NOT_INCREASE_ELEMENT_MIN_OCCURS, $from->getAttribute('minOccurs'), $to->getAttribute('minOccurs'), $xPath);
			}
				
			for($i = $from->getAttribute('minOccurs'); $i < $to->getAttribute('minOccurs'); $i++)
					$xsl .= '
			' . $tabs . '<xsl:element name="' . $toName . '">' . $to->getAttribute('default') . '
			' . $tabs . '</xsl:element>';
					
			$isIdentical = false;
			KalturaLog::info("Node [$toName] minimum occurs changed from [" . $from->getAttribute('minOccurs') . "] to [" . $to->getAttribute('minOccurs') . "]");
		}
		
		if($isIdentical)
			return true;

		//$xsl =  $tabs . $xsl;
			
		
		
		return $xsl;
	}
	
	public static function getElementById(DOMDocument $doc, $id)
	{
		$xpath = new DOMXpath($doc);

		$path = "//*[@id='$id']";
		KalturaLog::debug("Query xpath [$path]");
		$elements = $xpath->query($path);
		if(is_null($elements))
			return null;
			
		foreach ($elements as $element)
			return $element;
	}
	
	protected static function getMatchingElement($childrenArr, $element, &$index)
	{
		// try matching by id
		foreach($childrenArr as $curIndex => $curChild)
		{
			if(strtolower($curChild->localName) != strtolower($element->localName))
				continue;
				
			if($curChild->getAttribute('id') && 
				$curChild->getAttribute('id') != $element->getAttribute('id'))
				continue;
				
			$index = $curIndex;
			return $curChild;
		}
		
		// try matching by id
		foreach($childrenArr as $curIndex => $curChild)
		{
			if(strtolower($curChild->localName) != strtolower($element->localName))
				continue;
				
			if($curChild->getAttribute('name') && 
				$curChild->getAttribute('name') != $element->getAttribute('name'))
				continue;
				
			$index = $curIndex;
			return $curChild;
		}
		<commit_msg>qnd: kXsd bug fix - the code did not match correctly fields without id, if there are multiple fields without id it could match any field to any of them<commit_after><?php
/** 
 * @package infra
 * @subpackage utils
 */

class kXsd
{
	/**
	 * @param DOMNode $from old node
	 * @param DOMNode $to new node
	 * @param string $xPath
	 * @param int $level indentation level
	 * @return bool|string true if no change required, or, xsl text if transform required
	 * @throws kXsdException
	 */
	public static function compareElement(DOMNode $from, DOMNode $to, $parentXPath = '', $level = 1)
	{
		$toName = $to->getAttribute('name');
		$fromName = $from->getAttribute('name');
		KalturaLog::debug("Compare elements [$fromName] [$toName]");
		
		$xPath = $parentXPath . "/*[local-name()='$fromName']";
						
		if($from->getAttribute('type') != $to->getAttribute('type'))
		{
			KalturaLog::debug("Elements types are different [" . $from->getAttribute('type') . "] [" . $to->getAttribute('type') . "]");
			throw new kXsdException(kXsdException::CAN_NOT_CHANGE_ELEMENT_TYPE, $from->getAttribute('type'), $to->getAttribute('type'), $xPath);
		}
			
		if($from->getAttribute('maxOccurs') > $to->getAttribute('maxOccurs'))
		{
			KalturaLog::debug("Elements max occurs reduced [" . $from->getAttribute('maxOccurs') . "] [" . $to->getAttribute('maxOccurs') . "]");
			throw new kXsdException(kXsdException::CAN_NOT_REDUCE_ELEMENT_MAX_OCCURS, $from->getAttribute('maxOccurs'), $to->getAttribute('maxOccurs'), $xPath);
		}
			
		$tabs = str_repeat("\t", $level);
		
		
		$isIdentical = true;
		
		$restriction = self::getNodeRestrictions($to, $from);
		if (strlen($restriction)){
			$isIdentical = false;
		}
		
		$xsl = self::compareNode($from, $to, $xPath, $level + 1);
		if(is_bool($xsl))
		{
			if(!$xsl)
				return false;
				
			$xsl = '<xsl:value-of select="' . $parentXPath . $restriction .'/*[local-name()=\'' . $fromName . '\']"/>';
		}
		else 
		{
			$isIdentical = false;
			$xsl = '
		' . $tabs . '<xsl:element name="' . $toName . '">' . $xsl . '
		' . $tabs . '</xsl:element>';
		}
		
		if($fromName != $toName)
		{
			$isIdentical = false;
		}
		
		if(intval($to->getAttribute('minOccurs')) && $from->getAttribute('minOccurs') < $to->getAttribute('minOccurs'))
		{
			if(!$to->hasAttribute('default'))
			{
				KalturaLog::debug("Elements min occurs increased [" . $from->getAttribute('minOccurs') . "] [" . $to->getAttribute('minOccurs') . "]");
				throw new kXsdException(kXsdException::CAN_NOT_INCREASE_ELEMENT_MIN_OCCURS, $from->getAttribute('minOccurs'), $to->getAttribute('minOccurs'), $xPath);
			}
				
			for($i = $from->getAttribute('minOccurs'); $i < $to->getAttribute('minOccurs'); $i++)
					$xsl .= '
			' . $tabs . '<xsl:element name="' . $toName . '">' . $to->getAttribute('default') . '
			' . $tabs . '</xsl:element>';
					
			$isIdentical = false;
			KalturaLog::info("Node [$toName] minimum occurs changed from [" . $from->getAttribute('minOccurs') . "] to [" . $to->getAttribute('minOccurs') . "]");
		}
		
		if($isIdentical)
			return true;

		//$xsl =  $tabs . $xsl;
			
		
		
		return $xsl;
	}
	
	public static function getElementById(DOMDocument $doc, $id)
	{
		$xpath = new DOMXpath($doc);

		$path = "//*[@id='$id']";
		KalturaLog::debug("Query xpath [$path]");
		$elements = $xpath->query($path);
		if(is_null($elements))
			return null;
			
		foreach ($elements as $element)
			return $element;
	}
	
	protected static function getMatchingElement($childrenArr, $element, &$index)
	{
		// try matching by id
		if ($element->getAttribute('id'))
		{
			foreach($childrenArr as $curIndex => $curChild)
			{
				if(strtolower($curChild->localName) != strtolower($element->localName))
					continue;
					
				if(!$curChild->getAttribute('id') || 
					$curChild->getAttribute('id') != $element->getAttribute('id'))
					continue;
					
				$index = $curIndex;
				return $curChild;
			}
			
			return null;
		}
		
		// try matching by name
		if ($element->getAttribute('name'))
		{
			foreach($childrenArr as $curIndex => $curChild)
			{
				if(strtolower($curChild->localName) != strtolower($element->localName))
					continue;
					
				if(!$curChild->getAttribute('name') || 
					$curChild->getAttribute('name') != $element->getAttribute('name'))
					continue;
					
				$index = $curIndex;
				return $curChild;
			}
		}
		
		// try matching by local name only
		foreach($childrenArr as $curIndex => $curChild)
		{
			if(strtolower($curChild->localName) != strtolower($element->localName))
				continue;
				
			$index = $curIndex;
			return $curChild;
		}
		
{'fraction_non_alphanumeric': 0.19377162629757785, 'fraction_numerical': 0.000461361014994233, 'mean_word_length': 3.7176278563656147, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 100, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4000636', 'n_tokens_mistral': 3455, 'n_tokens_neox': 2958, 'n_words': 551}