有人能帮助我将其从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

查看:19
本文介绍了有人能帮助我将其从XSLT-2.0转换为XSLT-1.0吗?*更新*,尝试创建慕尼黑分组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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆