合并和继承参数
Merging and inheriting parameters
使用 xslt 版本 3.0 (撒克逊语):
我有类似下面的内容
<root>
<template ID='1'>
<params>
<a>1</a>
<b>1</b>
</params>
</template>
<document1 templateID='1'>
<params>
<b>4</b>
<c>5</c>
</params>
</document1>
</root>
基本上我需要转换成类似
的东西
<root>
<document1 templateID='1'>
<params>
<a>1</a>
<b>4</b>
<c>5</c>
</params>
</document1>
</root>
在示例中,参数 a
继承自模板,而参数 b
被文档本身覆盖,参数 c
未知或未在模板中设置。它类似于继承或 css 的工作方式。我希望你明白了。在开始任务之前,我认为这应该不会太难(并且仍然希望我只是忽略了一些东西)。
我已经尝试过连接两个节点集(使用 nodeset1 , nodeset2
来保留顺序)并使用基于 'select'/'filtering' 的前同级名称 - 但是这个策略似乎不起作用,因为它们似乎不是真正的兄弟姐妹。这可以通过一个聪明的 group-by 来完成吗?完全可以做到吗? (我觉得可以)
我正在使用 xslt 版本 3.0 (saxon)
我认为您想要分组或合并,在 XSLT 3 中合并将是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="template-by-id" match="template" use="@ID"/>
<xsl:template match="template"/>
<xsl:template match="*[@templateID]/params">
<xsl:copy>
<xsl:merge>
<xsl:merge-source name="template" select="key('template-by-id', ../@templateID)/params/*">
<xsl:merge-key select="string(node-name())"/>
</xsl:merge-source>
<xsl:merge-source name="doc" select="*">
<xsl:merge-key select="string(node-name())"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:copy-of select="(current-merge-group('doc'), current-merge-group('template'))[1]"/>
</xsl:merge-action>
</xsl:merge>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jyH9rN8/
分组为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="template-by-id" match="template" use="@ID"/>
<xsl:template match="template"/>
<xsl:template match="*[@templateID]/params">
<xsl:copy>
<xsl:for-each-group select="key('template-by-id', ../@templateID)/params/*, *" group-by="node-name()">
<xsl:copy-of select="head((current-group()[2], .))"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jyH9rN8/1
我认为,由于 xsl:merge
要求输入按任何合并键排序或首先对输入进行排序,上面的分组更容易和更可靠,除非您的 params
子元素确实是用字母表中排序的字母或单词命名。
使用 xslt 版本 3.0 (撒克逊语):
我有类似下面的内容
<root>
<template ID='1'>
<params>
<a>1</a>
<b>1</b>
</params>
</template>
<document1 templateID='1'>
<params>
<b>4</b>
<c>5</c>
</params>
</document1>
</root>
基本上我需要转换成类似
的东西 <root>
<document1 templateID='1'>
<params>
<a>1</a>
<b>4</b>
<c>5</c>
</params>
</document1>
</root>
在示例中,参数 a
继承自模板,而参数 b
被文档本身覆盖,参数 c
未知或未在模板中设置。它类似于继承或 css 的工作方式。我希望你明白了。在开始任务之前,我认为这应该不会太难(并且仍然希望我只是忽略了一些东西)。
我已经尝试过连接两个节点集(使用 nodeset1 , nodeset2
来保留顺序)并使用基于 'select'/'filtering' 的前同级名称 - 但是这个策略似乎不起作用,因为它们似乎不是真正的兄弟姐妹。这可以通过一个聪明的 group-by 来完成吗?完全可以做到吗? (我觉得可以)
我正在使用 xslt 版本 3.0 (saxon)
我认为您想要分组或合并,在 XSLT 3 中合并将是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="template-by-id" match="template" use="@ID"/>
<xsl:template match="template"/>
<xsl:template match="*[@templateID]/params">
<xsl:copy>
<xsl:merge>
<xsl:merge-source name="template" select="key('template-by-id', ../@templateID)/params/*">
<xsl:merge-key select="string(node-name())"/>
</xsl:merge-source>
<xsl:merge-source name="doc" select="*">
<xsl:merge-key select="string(node-name())"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:copy-of select="(current-merge-group('doc'), current-merge-group('template'))[1]"/>
</xsl:merge-action>
</xsl:merge>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jyH9rN8/
分组为
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="template-by-id" match="template" use="@ID"/>
<xsl:template match="template"/>
<xsl:template match="*[@templateID]/params">
<xsl:copy>
<xsl:for-each-group select="key('template-by-id', ../@templateID)/params/*, *" group-by="node-name()">
<xsl:copy-of select="head((current-group()[2], .))"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/jyH9rN8/1
我认为,由于 xsl:merge
要求输入按任何合并键排序或首先对输入进行排序,上面的分组更容易和更可靠,除非您的 params
子元素确实是用字母表中排序的字母或单词命名。