有人能帮助我将其从XSLT-2.0转换为XSLT-1.0吗?*更新*,尝试创建慕尼黑分组XSLT-1.0 [英] Can someone assist me in converting this from XSLT-2.0 to XSLT-1.0? *Update*, attempted to create Muenchian Grouping XSLT-1.0
问题描述
作为前言,我对XSLT-1.0知之甚少。我觉得我想要完成的事情似乎超出了初学者的能力范围。
通过这里的其他社区成员,我已经能够提出以下样式表:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/LaborTaskInterface" >
<xsl:copy>
<xsl:for-each select="LaborTask/ltOverride">
<xsl:copy>
<xsl:for-each-group select="../@* | @*" group-by="name()">
<xsl:for-each select="current-group()">
<xsl:element name="{name()}{if (position() > 1) then concat('.', position()) else ''}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这些年来,我搜索了社区内的其他帖子,但没有发现任何我认为可以比较的帖子。
但是,我相信XSLT-1.0使用Muenchian分组。但是,我不确定如何将其应用于上述样式表。
我有这个XSLT-1.0,它将包含的XML(如下所示)从以属性为中心转换为以元素为中心:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*" >
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我相信通过应用Muenchian方法,我可以模仿上面的XSLT-2.0所做的事情,只是不知道如何应用它。
我在以下内容中的关键字是什么:
<?xml version="1.0" encoding="UTF-8"?>
<LaborTaskInterface>
<LaborTask thing1="a" thing2="c" thing3="d" thing4="e" thing5="f"
thing6="g" thing7="h" thing8="i" thing9="j">
<ltOverride unit_id="1" value="1" thing2="k" thing3="c" thing4="d" thing10="o"/>
<ltOverride unit_id="2" value="1" thing2="l" thing3="c" thing4="d" thing11="p"/>
<ltOverride unit_id="3" value="1" thing2="m" thing3="c" thing4="d" thing12="q"/>
<ltOverride unit_id="4" value="1" thing2="n" thing3="c" thing4="d" thing13="r"/>
</LaborTask>
</LaborTaskInterface>
将上面的XSLT-1.0应用于我的XML时,我得到以下信息:
<LaborTaskInterface>
<LaborTask>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<ltOverride>
<unit_id>1</unit_id>
<value>1</value>
<thing2>k</thing2>
<thing3>c</thing3>
<thing4>d</thing4>
<thing10>o</thing10>
</ltOverride>
<ltOverride>
<unit_id>2</unit_id>
<value>1</value>
<thing2>l</thing2>
<thing3>c</thing3>
<thing4>d</thing4>
<thing11>p</thing11>
</ltOverride>
<ltOverride>
<unit_id>3</unit_id>
<value>1</value>
<thing2>m</thing2>
<thing3>c</thing3>
<thing4>d</thing4>
<thing12>q</thing12>
</ltOverride>
<ltOverride>
<unit_id>4</unit_id>
<value>1</value>
<thing2>n</thing2>
<thing3>c</thing3>
<thing4>d</thing4>
<thing13>r</thing13>
</ltOverride>
</LaborTask>
</LaborTaskInterface>
如您所见,每个ItOverride都不会重复"我的实验室任务",并且";空";节点不会出现在每个LabTask或ItOverride实例中。
有人可以帮助解释Muenchian Grouping方法的输入,并帮助我了解实现此样式表到XSLT-1.0的转换或如何将我的XSLT-1.0与上面包含的XSLT-2.0结合使用时可能需要应用的上述样式表的差异吗?
编辑,我进一步尝试使用慕尼黑方法
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="thing1_value" match="ItOverride" use="@thing1" />
<xsl:template match="LaborTask">
<AllLaborTask>
<xsl:apply-templates select="ItOverride[generate-id(.)=generate-id(key('thing1',@thing1)[1])]"/>
</AllLaborTask>
</xsl:template>
<xsl:template match="ItOverride">
<xsl:for-each select="key('task_id', @task_id)">
<ItOverride>
<thing1><xsl:value-of select="@thing1" /></thing1>
<unit_id><xsl:value-of select="@unit_id" /></unit_id>
<thing2><xsl:value-of select="@thing2" /></thing2>
<value><xsl:value-of select="@value" /></value>
<thing3><xsl:value-of select="@thing3" /></thing3>
<thing4><xsl:value-of select="@thing4" /></thing4>
<thing5><xsl:value-of select="@thing5" /></thing5>
<thing6><xsl:value-of select="@thing6" /></thing6>
<thing7><xsl:value-of select="@thing7" /></thing7>
<thing8><xsl:value-of select="@thing8" /></thing8>
<thing9><xsl:value-of select="@thing9" /></thing9>
<thing10><xsl:value-of select="@thing10" /></thing10>
<thing11><xsl:value-of select="@thing11" /></thing11>
<thing12><xsl:value-of select="@thing12" /></thing12>
<thing13><xsl:value-of select="@thing13" /></thing13>
</ItOverride>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这是上面提供的输出:
<AllLaborTask/>
对于我的完整XML(其中我有多个实验室任务,它只是以这样的方式重复:
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
<AllLaborTask/>
我们非常感谢您的任何帮助!TYIA!
使用msxml编辑运行此XSLT时,我在Access和用于调试的在线转换器工具中都收到错误:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxml">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="group" match="ltOverride/*" use="concat(generate-id(..), '|', name())"/>
<xsl:template match="LaborTask">
<xsl:variable name="temp-data">
<xsl:apply-templates select="ltOverride" mode="attributes-to-elements"/>
</xsl:variable>
<xsl:for-each select="mxsxml:node-set($temp-data)/ltOverride">
<xsl:copy>
<xsl:for-each select="*[generate-id() = generate-id(key('group', concat(generate-id(..), '|', name()))[1])]">
<xsl:for-each select="key('group', concat(generate-id(..), '|', name()))">
<xsl:variable name="index">
<xsl:if test="position() > 1">
<xsl:value-of select="concat('.', position())"/>
</xsl:if>
</xsl:variable>
<xsl:element name="{name()}{$index}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:template>
<xsl:template match="ltOverride" mode="attributes-to-elements">
<xsl:copy>
<xsl:apply-templates select="../@* | @*" mode="attributes-to-elements"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*" mode="attributes-to-elements">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
推荐答案
我认为对于xslt1,先展平再分组更容易:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="group" match="ltOverride/*" use="concat(generate-id(..), '|', name())"/>
<xsl:template match="LaborTask">
<xsl:variable name="temp-data">
<xsl:apply-templates select="ltOverride" mode="attributes-to-elements"/>
</xsl:variable>
<xsl:for-each select="exsl:node-set($temp-data)/ltOverride">
<xsl:copy>
<xsl:for-each select="*[generate-id() = generate-id(key('group', concat(generate-id(..), '|', name()))[1])]">
<xsl:for-each select="key('group', concat(generate-id(..), '|', name()))">
<xsl:variable name="index">
<xsl:if test="position() > 1">
<xsl:value-of select="concat('.', position())"/>
</xsl:if>
</xsl:variable>
<xsl:element name="{name()}{$index}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:template>
<xsl:template match="ltOverride" mode="attributes-to-elements">
<xsl:copy>
<xsl:apply-templates select="../@* | @*" mode="attributes-to-elements"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*" mode="attributes-to-elements">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XSLT 1要做到这一点,需要exsl:node-set
这样的扩展函数,具体取决于XSLT处理器Access的用途(早期版本的MS Office使用MSXML,在那里您必须使用xmlns:msxml="urn:schemas-microsoft-com:xslt"
和mxsxml:node-set
而不是exsl:node-set
)。您可能需要调整它,您说Access使用.NET,因此.NET中的XslCompiledTransform确实支持exsl:node-set
。
这篇关于有人能帮助我将其从XSLT-2.0转换为XSLT-1.0吗?*更新*,尝试创建慕尼黑分组XSLT-1.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!