dyn: valu () не оценивает правильно?

По какой-то причине мой запрос XPath не работает, когда выполняется внутри XSLT через dyn :valu (). Я использую PHP и hasEXSLTSupport() оценивает true

Вот мой сырой XML-документ:

<getListValues>
<node>
<Assignee>Assignee Value</Assignee>
<Summary>Summary Value</Summary>
<Incident_Number>Incident_Number Value</Incident_Number>
</node>
</getListValues>

Я использую это заявление XPath:

//node[Assignee!=""]/*[name()="Summary" or name()="Incident_Number" or  name()="Assignee"]

И в моем XSLT я использую этот раздел, чтобы проверить, работает ли он:

<xsl:variable name="elementValue" select="dyn:evaluate($query)" />
<xsl:value-of select="$elementValue" />

куда $query оценивает строку с выражением XPath (я знаю, потому что я проверил с xsl:value-of также).

Я не получаю никаких ошибок. На самом деле, делая <xsl:value-of select="boolean($elementValue)" /> оценивает false! Это означает, что ничего не возвращается.

Мои заголовки таблицы стилей:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dyn="http://exslt.org/dynamic" xmlns:php="http://php.net/xsl" extension-element-prefixes="dyn">

Кажется, что XPath просто не оценивается, даже если он совершенно корректен (я проверял PHP и Notepad ++ с расширением XPatherizerNPP). Что мне не хватает?

РЕДАКТИРОВАТЬ

Мои настоящие сценарии находятся в нескольких классах и папках, поэтому я публикую более простую версию того, что я запускаю. Это эквивалентно тому, что dyn: valu () по-прежнему не работает, хотя Notepad ++ говорит мне, что должен, и что я просто скопировал и вставил функции в другие классы в один для удобства.

мой mock.xml это скрипт, который я анализирую

<getListValues>
<node>
<Assignee>Assginee Value</Assignee>
<Summary>Summary Value</Summary>
<Incident_Number>Incident_Number Value</Incident_Number>
</node>

мой countFieldValues.xml Таблица стилей вызывает PHP для одновременного анализа отдельных поддеревьев в вызове функции readSubtree php.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dyn="http://exslt.org/dynamic" xmlns:php="http://php.net/xsl" extension-element-prefixes="dyn">

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

<xsl:template match="/">
<xsl:call-template name="nodeIterate" />
</xsl:template>

<xsl:template name="nodeIterate">
<xsl:variable name="subtree" select="php:functionString('xsltMaster::readSubtree', $dataset)" />
<xsl:if test="boolean($subtree)">
<xsl:apply-templates select="$subtree"/>
<xsl:call-template name="nodeIterate" />
</xsl:if>
</xsl:template>

<xsl:template match="node">
<br/>The current node: <xsl:value-of select="." /><br/>
<br/>The query: <xsl:value-of select="$query" /><br/>
<xsl:variable name="elementValue" select="dyn:evaluate($query)" />
<br/>What dyn:evaluate() evaluates to: <xsl:value-of select="boolean($elementValue)" /><br/>
<xsl:if test="boolean($elementValue)">
<xsl:for-each select="$elementValue">
<br/>What dyn:evaluate() evaluates to specifically: <xsl:value-of select="$elementValue" /><br/><br/>
</xsl:for-each>
<!--<xsl:variable name="archivist" select="php:functionString('xsltMaster::storeCount', $element, $elementValue)" />-->
</xsl:if>
</xsl:template>

</xsl:stylesheet>

мой testscript.php вызывает класс и выполняет все

<?php

require_once "class.php";
$source = "countFieldValues.xml";

$query = '//node[Assignee!=""]/*[name()="Summary" or name()="Incident_Number" or  name()="Assignee"]';
$test4 = new xsltMaster;
$test4->createXSLT($source);

$test4->processDataSet($query, "mock.xml", "processedMock.json");

мой class.php это процессор. Он использует классы XMLReader и XSLTProcessor в PHP.

<?php
class xsltMaster{

protected static $_read;
private $_xslt;
protected $_dom;

public function __construct(){
// load DOM XML
$this->_dom = new DOMDocument();
$this->_dom->loadXML('<root />');
}

/*
Creates the XSLT object on the currently loaded DOM document
If the XSLT is already loaded, it will delete it
It will then load the stylesheet
*/
public function createXSLT($xsl){
if(!empty($this->getXSLT())){
$this->deleteXSLT();
}
$xsldoc = new DOMDocument();
if(!$xsldoc->load($xsl)){
throw new PDOException('Failed to open XML stylesheet!');
}
$this->getXSLT(new XSLTProcessor())->importStyleSheet($xsldoc);
unset($xsldoc);

return true;
}

/*
Getters/setters for the XSLT processor
*/
protected function getXSLT($xslt=false){
if(!empty($xslt)){
$this->_xslt = $xslt;
}
return $this->_xslt;
}// this will register PHP functions and run PHP XMLReader inside XSLT
public function processDataSet($query, $source, $destination){
// set-up
$this->getXSLT()->registerPHPFunctions();
$this->getXSLT()->setParameter('', 'query', $query);
$this->getXSLT()->setParameter('', 'dataset', $source);
$this->getXSLT()->setProfiling('profile9.txt');
echo "has EXSLT support? ", var_dump($this->getXSLT()->hasEXSLTSupport()), "<br/>";

// execute
print $this->getXSLT()->transformToXML($this->_dom);
#file_put_contents($destination, json_encode(self::$_countList));

// clean up
$this->getXSLT()->removeParameter('', 'dataset');
$this->getXSLT()->removeParameter('', 'query');
}

public static function readSubtree($url=false){
// check if reader has already been initialized
if(empty(self::$_read)){
// if reader has not been initialized, check if a url is supplied
if(empty($url)) throw new PDOException("There is no file defined for transformation!");
// create the reader
self::$_read = new XMLReader;
self::$_read->open($url);
// loop until you reach the first node
while (self::$_read->name !== 'node'){
self::$_read->read();
}
} else {
// if the logic gets here, the reader has already initialized
// just move to the next node
self::$_read->next();
}
// once you find the first subtree, return it
// as long as we're still landing on a node element, return that expanded subtree
if(self::$_read->name === 'node'){
#echo "<pre>",var_dump(self::$_read->getReader()->expand()),"</pre>";
return self::$_read->expand();
}
// if it gets here, then we're at the bottom of the file
return null;
}

}

ОБНОВИТЬ:

Я нашел несколько выражений, для которых dyn:evaluate() возвращает наборы узлов.
Но они немного странные.

Вот когда они оценивают как истинное:

Assignee
Summary
Incident Number
*[name()="Assignee"]
*[name()="Assignee" and text()="Assignee Value"]

Но они оценивают как ложные:

*[Assignee="Assignee Value"]
//Assignee

В чем дело…?

ОБНОВИТЬ:

По предложению Майкла я провел его тест и получил такой результат:

<?xml version="1.0" encoding="UTF-8"?>
<results>
<processor>libxslt</processor>
<support>true</processor>
<path>/root/bravo</path>
<target/>
</results>

Часть отказа — цель, является пустым элементом.

1

Решение

Я бы посоветовал вам попробовать гораздо более простой тест и сообщить о результатах:

XML

<root>
<alpha/>
<bravo/>
<charlie/>
</root>

XSLT

<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:dyn="http://exslt.org/dynamic"extension-element-prefixes="dyn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="path" select="'/root/charlie'"/>

<xsl:template match="/">
<results>
<processor>
<xsl:value-of select="system-property('xsl:vendor')"/>
</processor>
<support>
<xsl:value-of select="function-available('dyn:evaluate')"/>
</support>
<path>
<xsl:value-of select="$path"/>
</path>
<target>
<xsl:copy-of select="dyn:evaluate($path)"/>
</target>
</results>
</xsl:template>

</xsl:stylesheet>

параметр

path = "/root/bravo"

Ожидаемый результат

<?xml version="1.0" encoding="UTF-8"?>
<results>
<processor>libxslt</processor>
<support>true</support>
<path>/root/bravo</path>
<target>
<bravo/>
</target>
</results>

2.

В ответ на ваши результаты:

Либо dyn :valu () не работает, несмотря на указания, либо что-то не так с тем, как вы передаете параметр. Это можно определить, добавив еще один элемент в тесты:

<verify>
<xsl:copy-of select="dyn:evaluate('/')"/>
</verify>

3.

Пожалуйста, попробуйте еще раз с этим:

<xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:dyn="http://exslt.org/dynamic"extension-element-prefixes="dyn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="path" select="'/root/charlie'"/>

<xsl:template match="/">
<results>
<processor>
<xsl:value-of select="system-property('xsl:vendor')"/>
</processor>
<support>
<xsl:value-of select="function-available('dyn:evaluate')"/>
</support>
<path>
<xsl:value-of select="$path"/>
</path>
<eval-param>
<xsl:copy-of select="dyn:evaluate($path)"/>
</eval-param>
<eval-string>
<xsl:copy-of select="dyn:evaluate('/root/charlie')"/>
</eval-string>
<copy>
<xsl:copy-of select="/root/charlie"/>
</copy>
</results>
</xsl:template>

</xsl:stylesheet>
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]