Skip to content

Commit

Permalink
fix output of namespaces when using xsl:copy-of in a xsl:for-each-gro…
Browse files Browse the repository at this point in the history
…up statement
  • Loading branch information
frederikbosch committed Aug 11, 2023
1 parent da05b91 commit 0128747
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/Callback/FunctionCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ final class FunctionCollection
/**
* @var array
*/
private $collection = [];
public $collection = [];

/**
* @param string $namespace
Expand Down
4 changes: 2 additions & 2 deletions src/Xpath/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ public function compile(string $xpathExpression, DOMNode $currentElement): strin
* @param DOMNode $currentElement
* @return string
*/
public function compileTokens(Lexer $tokens, DOMNode $currentElement): string
public function compileTokens(Lexer $tokens, DOMNode $currentElement, array $namespaces = []): string
{
$resultTokens = [];
foreach ($tokens as $token) {
foreach ($this->expressions as $expression) {
if ($expression->supports($tokens)) {
$resultTokens = $expression->merge($tokens, $currentElement, $resultTokens);
$resultTokens = $expression->merge($tokens, $currentElement, $resultTokens, $namespaces);
continue 2;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Xpath/Expression/DoubleQuoteExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function supports(Lexer $lexer): bool
* @param array $tokens
* @return array
*/
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens): array
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens, array $namespaces = []): array
{
$expression = $lexer->current();

Expand Down
2 changes: 1 addition & 1 deletion src/Xpath/Expression/ForLoopExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function supports(Lexer $lexer): bool
* @param array $tokens
* @return array
*/
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens): array
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens, array $namespaces = []): array
{
\array_splice(
$tokens,
Expand Down
10 changes: 5 additions & 5 deletions src/Xpath/Expression/FunctionExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,26 @@ public function supports(Lexer $lexer): bool
* @param array $tokens
* @return array
*/
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens): array
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens, array $namespaces = []): array
{
return \array_merge($tokens, $this->createFunctionTokens($lexer, $currentElement));
return \array_merge($tokens, $this->createFunctionTokens($lexer, $currentElement, $namespaces));
}

/**
* @param Lexer $lexer
* @param DOMNode $currentElement
* @return string[]
*/
private function createFunctionTokens(Lexer $lexer, DOMNode $currentElement)
private function createFunctionTokens(Lexer $lexer, DOMNode $currentElement, array $namespaces = [])
{
if ($currentElement->ownerDocument instanceof DOMDocument === false) {
throw new \UnexpectedValueException('Expecting currentElement attached to document');
}

$token = $lexer->current();
$documentElement = $currentElement->ownerDocument->documentElement;
$namespaces = FetchNamespacesFromNode::fetch($documentElement);
$functionQname = $this->convertTokenToFunctionName($token, $namespaces);
$documentNamespaces = \array_merge(FetchNamespacesFromNode::fetch($documentElement), $namespaces);
$functionQname = $this->convertTokenToFunctionName($token, $documentNamespaces);

try {
$dot = \strrpos($functionQname, ':');
Expand Down
2 changes: 1 addition & 1 deletion src/Xpath/Expression/SequenceExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function supports(Lexer $lexer): bool
* @param array $tokens
* @return array
*/
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens): array
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens, array $namespaces = []): array
{
return \array_merge($tokens, $this->sequenceConstructor->serialize($lexer, $currentElement));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Xpath/ExpressionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ public function supports(Lexer $lexer): bool;
* @param array $tokens
* @return array
*/
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens): array;
public function merge(Lexer $lexer, DOMNode $currentElement, array $tokens, array $namespaces = []): array;
}
6 changes: 1 addition & 5 deletions src/Xsl/Functions/GroupBy.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,8 @@ public static function distinct(Arguments $arguments, TransformationContext $con
/** @var DOMElement $current */
$current = $arguments->get(3)[0];

foreach ($namespaces as $prefix => $namespace) {
$current->ownerDocument->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $prefix, $namespace);
}

$compiler = new Compiler($context->getFunctions());
$xpathExpression = $compiler->compileTokens(Lexer::tokenize('string(' . $groupBy . ')'), $current);
$xpathExpression = $compiler->compileTokens(Lexer::tokenize('string(' . $groupBy . ')'), $current, $namespaces);

$values = [];
foreach ($list as $key => $element) {
Expand Down
14 changes: 14 additions & 0 deletions test/Integration/Xsl/ForEachGroupTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,20 @@ public function testWithNamespaceFunctions(): void
$this->assertEquals('201120152014', \trim($processor->transformToXml($data)));
}

public function testWithNamespaceFunctionsCopyOf(): void
{
$styleSheet = new DOMDocument();
$styleSheet->load('Stubs/Xsl/ForEachGroup/group-by-namespace-functions-copy-of.xsl');

$processor = new XsltProcessor(new NullCache());
$processor->importStyleSheet($styleSheet);

$data = new DOMDocument();
$data->load('Stubs/packages.xml');

$this->assertEquals('<div><p>test</p></div><div><p>test</p></div><div><p>test</p></div><div><p>test</p></div>', \trim($processor->transformToXml($data)));
}

public function testByAttributeValueTemplates(): void
{
$styleSheet = new DOMDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xsl:output omit-xml-declaration="yes" />

<xsl:template match="packages">

<xsl:for-each-group select="package" group-by="year-from-dateTime(xs:dateTime(year/@value))">
<xsl:for-each select="current-group()">
<div><xsl:copy-of select="content/node()" /></div>
</xsl:for-each>
</xsl:for-each-group>

</xsl:template>

</xsl:stylesheet>
4 changes: 4 additions & 0 deletions test/Stubs/packages.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<dependency name="a" author="Author1"/>
<dependency name="b" author="Author1"/>
<dependency name="c" author="Author2"/>
<content><p>test</p></content>
</package>
<package>
<author>Genkgo</author>
Expand All @@ -16,6 +17,7 @@
<dependency name="x" author="Author3"/>
<dependency name="y" author="Author4"/>
<dependency name="z" author="Author4"/>
<content><p>test</p></content>
</package>
<package>
<author>Genkgo</author>
Expand All @@ -25,6 +27,7 @@
<dependency name="h" author="Author5"/>
<dependency name="i" author="Author1"/>
<dependency name="j" author="Author2"/>
<content><p>test</p></content>
</package>
<package>
<author>Genkgo</author>
Expand All @@ -34,5 +37,6 @@
<dependency name="g" author="Author3"/>
<dependency name="h" author="Author4"/>
<dependency name="i" author="Author1"/>
<content><p>test</p></content>
</package>
</packages>

0 comments on commit 0128747

Please sign in to comment.