XSLT 1.0 分组将日期定义的元素重新格式化为任务定义的元素

发布于 2024-09-02 09:17:44 字数 1218 浏览 3 评论 0原文

我有一个棘手的 XSLT 转换,希望得到您的建议 我的 xml 格式如下:

<Person>
<name>John</name>
<date>June12</date>
<workTime taskID=1>34</workTime>
<workTime taskID=2>12</workTime>
</Person>
<Person>
<name>John</name>
<date>June12</date>
<workTime taskID=1>21</workTime>
<workTime taskID=2>11</workTime>
</Person>

输出 xml 应该是:

<Person>
<name>John</name>
<taskID>1</taskID>
<workTime>
    <date>June12</date>
    <time>34</time>
</worTime>
<workTime>
    <date>June13</date>
    <time>21</time>
</worTime>
</Person>
<Person>
<name>John</name>
<taskID>2</taskID>
<workTime>
    <date>June12</date>
    <time>12</time>
</worTime>
<workTime>
    <date>June13</date>
    <time>11</time>
</worTime>
</Person>

本质上,作为输入,“Person”对象收集特定日期的所有任务/工作时间。作为输出,我希望“Person”对象收集特定任务的日期/工作时间。

我需要使用 XLST 1.0。 我一直在尝试使用键分组,但感到非常困惑。

感谢您的帮助。 丹尼尔

I have a tricky XSLT transformation and I'd like your advise
My xml is formatted as below:

<Person>
<name>John</name>
<date>June12</date>
<workTime taskID=1>34</workTime>
<workTime taskID=2>12</workTime>
</Person>
<Person>
<name>John</name>
<date>June12</date>
<workTime taskID=1>21</workTime>
<workTime taskID=2>11</workTime>
</Person>

The output xml should be:

<Person>
<name>John</name>
<taskID>1</taskID>
<workTime>
    <date>June12</date>
    <time>34</time>
</worTime>
<workTime>
    <date>June13</date>
    <time>21</time>
</worTime>
</Person>
<Person>
<name>John</name>
<taskID>2</taskID>
<workTime>
    <date>June12</date>
    <time>12</time>
</worTime>
<workTime>
    <date>June13</date>
    <time>11</time>
</worTime>
</Person>

Essentially, as an input, a "Person" object gathers all the task/workTime for a specific date. As an output, I want the "Person" object to gather the date/workTime for a specific task.

I need to use XLST 1.0.
I've been trying to use grouping with key but get very puzzled.

Appreciate your help.
Daniel

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

北座城市 2024-09-09 09:17:44

我相信解决这个问题的一种方法是使用 muenchian 分组,但在这种情况下,您是按任务和人员分组,因此您需要一个聚合键,

<xsl:key name="PersonTasks" match="workTime" use="concat(@taskID, ../name)"/>

该键用于查找所有不同的“人员任务”。您可以通过执行以下操作来迭代此操作

<xsl:apply-templates select="//workTime[generate-id() = generate-id(key('PersonTasks',concat(@taskID, ../name))[1])]"/>

然后,对于每个不同的 Person 和 TaskID,您只需找到所有工作时间。尝试这个样式表(注意我添加了一个“People”元素,为输出提供单个根元素以确保它是有效的 XML)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:key name="PersonTasks" match="workTime" use="concat(@taskID, ../name)"/>

   <xsl:template match="/">
      <People>
         <xsl:apply-templates select="//workTime[generate-id() = generate-id(key('PersonTasks',concat(@taskID, ../name))[1])]"/>
      </People>
   </xsl:template>

   <xsl:template match="workTime">
      <xsl:variable name="taskID">
         <xsl:value-of select="@taskID"/>
      </xsl:variable>
      <xsl:variable name="name">
         <xsl:value-of select="../name"/>
      </xsl:variable>
      <Person>
         <name>
            <xsl:value-of select="$name"/>
         </name>
         <taskID>
            <xsl:value-of select="$taskID"/>
         </taskID>
         <xsl:for-each select="//workTime[../name = $name][@taskID = $taskID]">
            <workTime>
               <date>
                  <xsl:value-of select="../date"/>
               </date>
               <time>
                  <xsl:value-of select="."/>
               </time>
            </workTime>
         </xsl:for-each>
      </Person>
   </xsl:template>

</xsl:stylesheet>

当您将其应用于以下输入 XML 时,

<People>
<Person>             
<name>John</name>             
<date>June12</date>             
<workTime taskID="1">34</workTime>             
<workTime taskID="2">12</workTime>             
</Person>             
<Person>             
<name>John</name>             
<date>June13</date>             
<workTime taskID="1">21</workTime>             
<workTime taskID="2">11</workTime>             
</Person>   
</People>

您应该获得以下输出

<People>
   <Person>
      <name>John</name>
      <taskID>1</taskID>
      <workTime>
         <date>June12</date>
         <time>34</time>
      </workTime>
      <workTime>
         <date>June13</date>
         <time>21</time>
      </workTime>
   </Person>
   <Person>
      <name>John</name>
      <taskID>2</taskID>
      <workTime>
         <date>June12</date>
         <time>12</time>
      </workTime>
      <workTime>
         <date>June13</date>
         <time>11</time>
      </workTime>
   </Person>
</People>

I believe one way to solve it is to use muenchian grouping, but in this case you are grouping by task and by person, and so you need an aggregated key

<xsl:key name="PersonTasks" match="workTime" use="concat(@taskID, ../name)"/>

This key is used to look up all distinct 'person tasks'. You would iterate over this by doing the following

<xsl:apply-templates select="//workTime[generate-id() = generate-id(key('PersonTasks',concat(@taskID, ../name))[1])]"/>

Then, for each distinct Person and TaskID, you just need to find all the work times. Try this stylesheet (Note I have added a 'People' element, to give the output a single root element to ensure it is valid XML)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:key name="PersonTasks" match="workTime" use="concat(@taskID, ../name)"/>

   <xsl:template match="/">
      <People>
         <xsl:apply-templates select="//workTime[generate-id() = generate-id(key('PersonTasks',concat(@taskID, ../name))[1])]"/>
      </People>
   </xsl:template>

   <xsl:template match="workTime">
      <xsl:variable name="taskID">
         <xsl:value-of select="@taskID"/>
      </xsl:variable>
      <xsl:variable name="name">
         <xsl:value-of select="../name"/>
      </xsl:variable>
      <Person>
         <name>
            <xsl:value-of select="$name"/>
         </name>
         <taskID>
            <xsl:value-of select="$taskID"/>
         </taskID>
         <xsl:for-each select="//workTime[../name = $name][@taskID = $taskID]">
            <workTime>
               <date>
                  <xsl:value-of select="../date"/>
               </date>
               <time>
                  <xsl:value-of select="."/>
               </time>
            </workTime>
         </xsl:for-each>
      </Person>
   </xsl:template>

</xsl:stylesheet>

When you apply this to the following input XML

<People>
<Person>             
<name>John</name>             
<date>June12</date>             
<workTime taskID="1">34</workTime>             
<workTime taskID="2">12</workTime>             
</Person>             
<Person>             
<name>John</name>             
<date>June13</date>             
<workTime taskID="1">21</workTime>             
<workTime taskID="2">11</workTime>             
</Person>   
</People>

You should get the following output

<People>
   <Person>
      <name>John</name>
      <taskID>1</taskID>
      <workTime>
         <date>June12</date>
         <time>34</time>
      </workTime>
      <workTime>
         <date>June13</date>
         <time>21</time>
      </workTime>
   </Person>
   <Person>
      <name>John</name>
      <taskID>2</taskID>
      <workTime>
         <date>June12</date>
         <time>12</time>
      </workTime>
      <workTime>
         <date>June13</date>
         <time>11</time>
      </workTime>
   </Person>
</People>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文