/** * @testdox minify() tests * @dataProvider getMinifyTests */ public function testMinify($original, $expected) { if ($expected instanceof Exception) { $this->setExpectedException(get_class($expected), $expected->getMessage()); } $this->assertSame($expected, XPathHelper::minify($original)); }
/** * Remove extraneous space in XPath expressions used in XSL elements * * @param DOMElement $template <xsl:template/> node * @return void */ public function normalize(DOMElement $template) { $xpath = new DOMXPath($template->ownerDocument); // Get all the "match", "select" and "test" attributes of XSL elements, whose value contains // a space $query = '//xsl:*/@*[contains(., " ")][contains("matchselectest", name())]'; foreach ($xpath->query($query) as $attribute) { $attribute->parentNode->setAttribute($attribute->nodeName, XPathHelper::minify($attribute->nodeValue)); } // Get all the attributes of non-XSL elements, whose value contains a space $query = '//*[namespace-uri() != "' . self::XMLNS_XSL . '"]' . '/@*[contains(., " ")]'; foreach ($xpath->query($query) as $attribute) { AVTHelper::replace($attribute, function ($token) { if ($token[0] === 'expression') { $token[1] = XPathHelper::minify($token[1]); } return $token; }); } }
/** * Generate the dynamic template that renders all emoticons * * @return string */ public function getTemplate() { // Build the <xsl:choose> node $xsl = '<xsl:choose>'; // First, test whether the emoticon should be rendered as text if applicable if (!empty($this->notIfCondition)) { $xsl .= '<xsl:when test="' . htmlspecialchars($this->notIfCondition) . '">' . '<xsl:value-of select="."/>' . '</xsl:when>' . '<xsl:otherwise>' . '<xsl:choose>'; } // Iterate over codes, create an <xsl:when> for each emote foreach ($this->collection as $code => $template) { $xsl .= '<xsl:when test=".=' . htmlspecialchars(XPathHelper::export($code)) . '">' . $template . '</xsl:when>'; } // Finish it with an <xsl:otherwise> that displays the unknown codes as text $xsl .= '<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>'; // Close the emote switch $xsl .= '</xsl:choose>'; // Close the "notIf" condition if applicable if (!empty($this->notIfCondition)) { $xsl .= '</xsl:otherwise></xsl:choose>'; } return $xsl; }
public function getTemplate() { $xsl = '<xsl:choose>'; if (!empty($this->notIfCondition)) { $xsl .= '<xsl:when test="' . \htmlspecialchars($this->notIfCondition) . '"><xsl:value-of select="."/></xsl:when><xsl:otherwise><xsl:choose>'; } foreach ($this->collection as $code => $template) { $xsl .= '<xsl:when test=".=' . \htmlspecialchars(XPathHelper::export($code)) . '">' . $template . '</xsl:when>'; } $xsl .= '<xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>'; $xsl .= '</xsl:choose>'; if (!empty($this->notIfCondition)) { $xsl .= '</xsl:otherwise></xsl:choose>'; } return $xsl; }
/** * {@inheritdoc} */ protected function isExpressionSafe($expr) { return XPathHelper::isExpressionNumeric($expr); }
/** * Return a list of parameters in use in given XSL * * @param string $xsl XSL source * @return array Alphabetically sorted list of unique parameter names */ public static function getParametersFromXSL($xsl) { $paramNames = []; // Wrap the XSL in boilerplate code because it might not have a root element $xsl = '<xsl:stylesheet xmlns:xsl="' . self::XMLNS_XSL . '">' . '<xsl:template>' . $xsl . '</xsl:template>' . '</xsl:stylesheet>'; $dom = new DOMDocument(); $dom->loadXML($xsl); $xpath = new DOMXPath($dom); // Start by collecting XPath expressions in XSL elements $query = '//xsl:*/@match | //xsl:*/@select | //xsl:*/@test'; foreach ($xpath->query($query) as $attribute) { foreach (XPathHelper::getVariables($attribute->value) as $varName) { // Test whether this is the name of a local variable $varQuery = 'ancestor-or-self::*/' . 'preceding-sibling::xsl:variable[@name="' . $varName . '"]'; if (!$xpath->query($varQuery, $attribute)->length) { $paramNames[] = $varName; } } } // Collecting XPath expressions in attribute value templates $query = '//*[namespace-uri() != "' . self::XMLNS_XSL . '"]' . '/@*[contains(., "{")]'; foreach ($xpath->query($query) as $attribute) { $tokens = AVTHelper::parse($attribute->value); foreach ($tokens as $token) { if ($token[0] !== 'expression') { continue; } foreach (XPathHelper::getVariables($token[1]) as $varName) { // Test whether this is the name of a local variable $varQuery = 'ancestor-or-self::*/' . 'preceding-sibling::xsl:variable[@name="' . $varName . '"]'; if (!$xpath->query($varQuery, $attribute)->length) { $paramNames[] = $varName; } } } } // Dedupe and sort names $paramNames = array_unique($paramNames); sort($paramNames); return $paramNames; }