/** * Inline the text content of a node or the value of an attribute where it's known * * Will replace * <xsl:if test="@foo='Foo'"><xsl:value-of select="@foo"/></xsl:if> * with * <xsl:if test="@foo='Foo'">Foo</xsl:if> * * @param DOMElement $template <xsl:template/> node * @return void */ public function normalize(DOMElement $template) { $xpath = new DOMXPath($template->ownerDocument); $query = '//xsl:if | //xsl:when'; foreach ($xpath->query($query) as $node) { // Test whether the map has exactly one key and one value $map = TemplateParser::parseEqualityExpr($node->getAttribute('test')); if ($map === false || count($map) !== 1 || count($map[key($map)]) !== 1) { continue; } $expr = key($map); $value = end($map[$expr]); $this->inlineInferredValue($node, $expr, $value); } }
protected static function collectCompatibleBranches(DOMNode $node) { $nodes = array(); $key = \null; $values = array(); while ($node && self::isXslWhen($node)) { $branch = TemplateParser::parseEqualityExpr($node->getAttribute('test')); if ($branch === \false || \count($branch) !== 1) { break; } if (isset($key) && \key($branch) !== $key) { break; } if (\array_intersect($values, \end($branch))) { break; } $key = \key($branch); $values = \array_merge($values, \end($branch)); $nodes[] = $node; $node = $node->nextSibling; } return $nodes; }
/** * Collect consecutive xsl:when elements that share the same kind of equality tests * * Will return xsl:when elements that test a constant part (e.g. a literal) against the same * variable part (e.g. the same attribute) * * @param DOMNode $node First node to inspect * @return DOMElement[] */ protected static function collectCompatibleBranches(DOMNode $node) { $nodes = []; $key = null; $values = []; while ($node && self::isXslWhen($node)) { $branch = TemplateParser::parseEqualityExpr($node->getAttribute('test')); if ($branch === false || count($branch) !== 1) { // The expression is not entirely composed of equalities, or they have a different // variable part break; } if (isset($key) && key($branch) !== $key) { // Not the same variable as our branches break; } if (array_intersect($values, end($branch))) { // Duplicate values across branches, e.g. ".=1 or .=2" and ".=2 or .=3" break; } $key = key($branch); $values = array_merge($values, end($branch)); // Record this node then move on to the next sibling $nodes[] = $node; $node = $node->nextSibling; } return $nodes; }
/** * @dataProvider getParseEqualityExprTests */ public function testParseEqualityExpr($expr, $expected) { $this->assertSame($expected, TemplateParser::parseEqualityExpr($expr)); }