public static function buildXpath($segments, $prefix = '//')
{
$tagName = isset($segments['tag']) ? $segments['tag'] : '*';
$attributes = [];
// if the id attribute specified
if (isset($segments['id'])) {
$attributes[] = sprintf('@id="%s"', $segments['id']);
}
// if the class attribute specified
if (isset($segments['classes'])) {
foreach ($segments['classes'] as $class) {
$attributes[] = sprintf('contains(concat(" ", normalize-space(@class), " "), " %s ")', $class);
}
}
// if the attributes specified
if (isset($segments['attributes'])) {
foreach ($segments['attributes'] as $name => $value) {
$attributes[] = self::convertAttribute($name, $value);
}
}
// if the pseudo class specified
if (isset($segments['pseudo'])) {
$expression = isset($segments['expr']) ? trim($segments['expr']) : '';
$parameters = explode(',', $expression);
$attributes[] = self::convertPseudo($segments['pseudo'], $parameters, $tagName);
}
if (count($attributes) === 0 and !isset($segments['tag'])) {
throw new InvalidArgumentException('The array of segments should contain the name of the tag or at least one attribute');
}
$xpath = $prefix . $tagName;
if ($count = count($attributes)) {
$xpath .= $count > 1 ? sprintf('[(%s)]', implode(') and (', $attributes)) : sprintf('[%s]', $attributes[0]);
}
return $xpath;
}