(Обновлено больше)
ОК, часть проблемы становится понятной. Во-первых, просто чтобы убедиться, что я понимаю, вы на самом деле не передаете параметры для $files
и $root
в вызов процессора XSLT, верно? (Они могут также быть переменными, а не параметрами?)
Теперь к основным вопросам ... В XPath, когда вы оцениваете выражение, начинающееся с "/" (включая "//"), узел контекста игнорируется [в основном] . Поэтому, когда у вас есть
<xsl:template match="RootNode">
<xsl:for-each select="//Node">
соответствующий RootNode игнорируется. Может быть, вы хотели
<xsl:template match="RootNode">
<xsl:for-each select=".//Node">
в котором for-each будет выбирать элементы Node, которые являются потомками соответствующего RootNode? Это решило бы вашу проблему создания списка нужных узлов дважды.
Я вставил [в основном] выше, потому что я вспомнил, что «путь абсолютного местоположения» начинается с «корневого узла документа, содержащего узел контекста». Таким образом, контекстный узел влияет на то, какой документ используется для "// узла". Может быть, это то, что вы намеревались все время? Я думаю, что я не спешил, чтобы понять это.
(примечание: как отмечено в комментарии
а) на этой странице document () видимо
меняет корневой узел, возможно
объясняя это поведение.)
или точнее ,
Абсолютный путь к местоположению ["/ ..."]
с последующим относительным местоположением
путь ... выбирает набор узлов, которые
будет выбран родственником
путь локации относительно корня
узел документа, содержащего
контекстный узел .
document()
на самом деле ничего не меняет, в смысле побочных эффектов; скорее он возвращает набор узлов, содержащихся (обычно) в разных документах, чем первичный исходный документ. Инструкции XSLT, такие как xsl:apply-templates
и xsl:for-each
, устанавливают новые значения для узла контекста внутри области действия их шаблонных тел. Так что если вы используете xsl:apply-templates
и xsl:for-each
с select = "document (...) / ...", узел контекста внутри области действия этих инструкций будет принадлежать внешнему документу, поэтому любое использование "/. .. "как XPath начнется с этого внешнего документа.
Обновлен снова
Как я могу переопределить $ root, используя
объединенный XML в качестве источника вместо
из нескольких источников через document (), так
что список составляется только один раз,
не касаясь остальной части
XSLT?
Как намекнул @Alej, это действительно невозможно, учитывая вышеуказанное ограничение. Если вы выбираете «// Узел» в каждой итерации цикла над «$ root / RootNode», то для каждой итерации , а не , чтобы выбрать те же узлы, что и другие итерации, каждое значение «$ root / RootNode» должен быть в другом документе. Поскольку вы используете комбинированный источник XML вместо нескольких источников, это невозможно.
Но если вы не настаиваете на том, что ваше <xsl:for-each select="//...">
выражение XPath не может измениться, оно становится очень легким. :-) Просто вставьте "." перед "//".
Это похоже на то, что если $ root определен с помощью функции document (), общего корневого узла нет
в парам.
Значение параметра является набором узлов. Все узлы в наборе могут содержаться в одном и том же документе или нет, в зависимости от того, является ли первый аргумент document () набором узлов или просто одним узлом.
Можно ли определить параметр с двумя "отдельными" деревьями узлов?
Я полагаю, под «отдельным» вы подразумеваете «принадлежность к разным документам»? Да, это так, но я не думаю, что вы можете сделать это в XSLT 1.0, если вы сначала не выбираете узлы, которые принадлежат разным документам.
Вы упомянули попытку
<xsl:param name="root">
<xsl:for-each select="/TempNode/*">
<xsl:document>
<xsl:copy-of select="."/>
</xsl:document>
</xsl:for-each>
</xsl:param>
, но <xsl:document>
не определено в XSLT 1.0, и ваша таблица стилей сообщает version = "1.0". У вас есть XSLT 2.0? Если это так, дайте нам знать, и мы сможем воспользоваться этим вариантом. Если честно, <xsl:document>
для меня не знакомая территория. Но я рад учиться вместе с тобой.