static function f_Xml_FindTag(&$Txt, $Tag, $Opening, $PosBeg, $Forward, $LevelStop, $WithPrm, $WithPos = false) { /* This function is a smart solution to find an XML tag. It allows to ignore full opening/closing couple of tags that could be inserted before the searched tag. It allows also to pass a number of encapsulations. To ignore encapsulation and opengin/closing just set $LevelStop=false. */ if ($Tag === '_') { // New line $p = clsTinyButStrong::f_Xml_FindNewLine($Txt, $PosBeg, $Forward, $LevelStop !== 0); $Loc = new clsTbsLocator(); $Loc->PosBeg = $Forward ? $PosBeg : $p; $Loc->PosEnd = $Forward ? $p : $PosBeg; $Loc->RightLevel = 0; return $Loc; } $Pos = $PosBeg + ($Forward ? -1 : +1); $TagIsOpening = false; $TagClosing = '/' . $Tag; $LevelNum = 0; $TagOk = false; $PosEnd = false; $TagL = strlen($Tag); $TagClosingL = strlen($TagClosing); $RightLevel = 0; do { // Look for the next tag def if ($Forward) { $Pos = strpos($Txt, '<', $Pos + 1); } else { if ($Pos <= 0) { $Pos = false; } else { $Pos = strrpos(substr($Txt, 0, $Pos - 1), '<'); // strrpos() syntax compatible with PHP 4 } } if ($Pos !== false) { // Check the name of the tag if (strcasecmp(substr($Txt, $Pos + 1, $TagL), $Tag) == 0) { $PosX = $Pos + 1 + $TagL; // The next char $TagOk = true; $TagIsOpening = true; } elseif (strcasecmp(substr($Txt, $Pos + 1, $TagClosingL), $TagClosing) == 0) { $PosX = $Pos + 1 + $TagClosingL; // The next char $TagOk = true; $TagIsOpening = false; } if ($TagOk) { // Check the next char $x = $Txt[$PosX]; if ($x === ' ' or $x === "\r" or $x === "\n" or $x === '>' or $Tag === '/' or $Tag === '') { // Check the encapsulation count if ($LevelStop === false) { // No encaplusation check if ($TagIsOpening !== $Opening) { $TagOk = false; } } else { // Count the number of level if ($TagIsOpening) { $PosEnd = strpos($Txt, '>', $PosX); if ($PosEnd !== false) { if ($Txt[$PosEnd - 1] === '/') { if ($Pos < $PosBeg and $PosEnd > $PosBeg) { $RightLevel = 1; $LevelNum++; } } else { $LevelNum++; } } } else { $LevelNum--; } // Check if it's the expected level if ($LevelNum != $LevelStop) { $TagOk = false; $PosEnd = false; } } } else { $TagOk = false; } } //--> if ($TagOk) } } while ($Pos !== false and $TagOk === false); // Search for the end of the tag if ($TagOk) { $Loc = new clsTbsLocator(); if ($WithPrm) { clsTinyButStrong::f_Loc_PrmRead($Txt, $PosX, true, '\'"', '<', '>', $Loc, $PosEnd, $WithPos); } elseif ($PosEnd === false) { $PosEnd = strpos($Txt, '>', $PosX); if ($PosEnd === false) { $TagOk = false; } } } // Result if ($TagOk) { $Loc->PosBeg = $Pos; $Loc->PosEnd = $PosEnd; $Loc->RightLevel = $RightLevel; return $Loc; } else { return false; } }
function f_Xml_FindTag(&$Txt,$Tag,$Opening,$PosBeg,$Forward,$LevelStop,$WithPrm) { /* This function is a smarter issue to find an HTML tag. It enables to ignore full opening/closing couple of tag that could be inserted before the searched tag. It also enables to pass a number of encapsulations. To ignore encapsulation and opengin/closing just set $LevelStop=false. */ if ($Tag==='_') { // New line $p = clsTinyButStrong::f_Xml_FindNewLine($Txt,$PosBeg,$Forward,($LevelStop!==0)); $Loc = new clsTbsLocator; $Loc->PosBeg = ($Forward) ? $PosBeg : $p; $Loc->PosEnd = ($Forward) ? $p : $PosBeg; return $Loc; } $Pos = $PosBeg + (($Forward) ? -1 : +1); $TagIsOpening = false; $TagClosing = '/'.$Tag; $LevelNum = 0; $TagOk = false; do { // Look for the next tag def if ($Forward) { $Pos = strpos($Txt,'<',$Pos+1); } else { if ($Pos<=0) { $Pos = false; } else { $Pos = strrpos(substr($Txt,0,$Pos - 1),'<'); } } if ($Pos!==false) { // Check the name of the tag if (strcasecmp(substr($Txt,$Pos+1,mb_strlen($Tag)),$Tag)==0) { $PosX = $Pos + 1 + mb_strlen($Tag); // The next char $TagOk = true; $TagIsOpening = true; } elseif (strcasecmp(substr($Txt,$Pos+1,mb_strlen($TagClosing)),$TagClosing)==0) { $PosX = $Pos + 1 + mb_strlen($TagClosing); // The next char $TagOk = true; $TagIsOpening = false; } if ($TagOk) { // Check the next char $x = $Txt[$PosX]; if (($x===' ') or ($x==="\r") or ($x==="\n") or ($x==='>')) { // Check the encapsulation count if ($LevelStop===false) { // No encaplusation check if ($TagIsOpening!==$Opening) $TagOk = false; } else { // Count the number of level if ($TagIsOpening) { $LevelNum++; } else { $LevelNum--; } // Check if it's the expected level if ($LevelNum!=$LevelStop) $TagOk = false; } } else { $TagOk = false; } } //--> if ($TagOk) } } while (($Pos!==false) and ($TagOk===false)); // Search for the end of the tag if ($TagOk) { $Loc = new clsTbsLocator; if ($WithPrm) { $PosEnd = 0; clsTinyButStrong::f_Loc_PrmRead($Txt,$PosX,true,'\'"','<','>',$Loc,$PosEnd); } else { $PosEnd = strpos($Txt,'>',$PosX); if ($PosEnd===false) { $TagOk = false; } } } // Result if ($TagOk) { $Loc->PosBeg = $Pos; $Loc->PosEnd = $PosEnd; return $Loc; } else { return false; } }