English 中文(简体)
有条件地 Nest取多个异常低价竞标模板
原标题:Nesting multiple XSLT templates conditionally
  • 时间:2011-11-16 16:12:26
  •  标签:
  • xslt

我的XML非常平坦。

<Rows>
  <Row>
    <ProjectID>1000</ProjectID>
    <Phase>Initiation</Phase>
    <ID>1</ID>
    <Name>Work item 1</Name>
    <Master>1</Master>
  </Row>
  <Row>
    <ProjectID>1000</ProjectID>
    <Phase>Initiation</Phase>
    <ID>2</ID>
    <Name>Work item 2</Name>
    <Master>1</Master>
  </Row>
  <Row>
    <ProjectID>1000</ProjectID>
    <Phase>Closing</Phase>
    <ID>3</ID>
    <Name>Work item 3</Name>
    <Master>3</Master>
  </Row>
  <Row>
    <ProjectID>1000</ProjectID>
    <Phase>Closing</Phase>
    <ID>4</ID>
    <Name>Work item 4</Name>
    <Master>3</Master>
  </Row>
  <Row>
    <ProjectID>1000</ProjectID>
    <Phase>Closing</Phase>
    <ID>5</ID>
    <Name>Work item 5</Name>
    <Master>4</Master>
  </Row>
</Rows>

必须以这样的方式加以保护:

**Initiation**
Work item 1
  Work item 2
**Closing**
  Work item 3
    Work item 4
      Work item 5

现在,我有一个项目信息数据库、阶段和名称模板(例如,我的实际模板相当庞大),我开始在项目信息数据库模板、按阶段分类的组群和 lo中,然后按逐个名称分类。 (So,我收到按项目分列的所有姓名清单。) 它只为两个层次做了大量工作(即工作项目1和2),但第三个层次(如工作项目5)失去了我。

现在,我试图在名称模板的所有对应领域(其真实代码在这里):

<xsl:template name="Deliverable">
    <!--
Parent == True && Lone == True -> Impossible
Parent == True && Lone == False -> Parent
Parent == False && Lone == False -> Child
Parent == False && Lone = True -> Single deliverable -->

    <xsl:param name="parent" />
    <xsl:param name="lone" />

    <xsl:variable name="Parent">
      <xsl:choose>
        <xsl:when test="count(key( project-phase-deliverables , concat(ProjectNo,  | , Phase,  | , IDField2))) > 1">
          1
        </xsl:when>
        <xsl:otherwise>
          0
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="ID"><xsl:value-of select="generate-id(IDField1)" /></xsl:variable>

    <tr>
      <xsl:choose>
        <!-- JS for parent deliverable -->
        <xsl:when test="$Parent =  True ">
          <xsl:attribute name="ID">
            <xsl:value-of select="$ID"/>
          </xsl:attribute>
          <script>$( #<xsl:value-of select="$ID"/> ).click(function() { $( .<xsl:value-of select="IDField2"/> ).toggle(); });</script>
        </xsl:when>
        <!-- Coloring/attributes for children -->
        <xsl:when test="$parent =  False  and $lone= False ">
          <xsl:attribute name="style">background: #DEDEFF; display: none;</xsl:attribute>
          <xsl:attribute name="class">
            <xsl:value-of select="IDField2"/>
          </xsl:attribute>
        </xsl:when>
      </xsl:choose>

      <td class="doWhite" style="width: 15px; height: 24px; text-align:right; border-right:none;">
        <p class="normal">
          <!-- Parent deliverable expander arrow -->
          <xsl:if test="$Parent = 1">
            <span class="Expander">&#9654;</span>
          </xsl:if>
        </p>
      </td>
      <td class="doWhite" style="width: 200px; height: 24px; border-left:none;">
        <p class="normal">
          <!-- Child deliverable diamond -->
          <xsl:if test="$parent =  False  and $lone =  False ">
            <span class="Expander">&#9670; </span>
          </xsl:if>
          <xsl:value-of select="ItemDescription"/>
        </p>
      </td>
      <td class="doWhite" style="width: 130px; height: 24px">
        <p class="normal">
          <xsl:value-of select="Owner"/>
        </p>
      </td>
      <td style="width: 60px; height: 24px">
        <xsl:call-template name="status"/>
      </td>
      <td class="doWhite">
        <p class="normal">
          <xsl:value-of select="ItemNotes"/>
        </p>
      </td>
    </tr>
    <xsl:if test="$Parent = 1">
      <xsl:for-each select="key( project-phase-deliverables , concat(ProjectNo,  | , Phase,  | , IDField2))[position()!=1]">
        <!-- this doesn t recurse properly :( -->
        <xsl:call-template name="Deliverable" />
      </xsl:for-each>
    </xsl:if>
  </xsl:template>

And as you can expect, that loops infinitely and times out. I feel like I can use apply-template for my problem but how can I use that to effectively group by the other fields (Phase and ProjectID) ?

最佳回答

我可能误解了你的要求,但认为你可能在此重复。

首先,我想到的是Phase。 因此,建立了这样一个关键:

<xsl:key name="Phase" match="Row" use="Phase" />

每一次<>低温>

<xsl:apply-templates 
  select="//Row[generate-id() = generate-id(key( Phase , Phase)[1])]"
  mode="first" />

为了让现在的后代了解,你可以重新把模板称作。 页: 1

<xsl:apply-templates 
  select="//Row[Phase=current()/Phase][Master=current()/ID][Master != ID]" />

因此,考虑到以下SLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="Phase" match="Row" use="Phase"/>

   <xsl:template match="/">
      <Rows>
         <xsl:apply-templates select="//Row[generate-id() = generate-id(key( Phase , Phase)[1])]" mode="first"/>
      </Rows>
   </xsl:template>

   <xsl:template match="Row" mode="first">
      <Phase name="{Phase}">
         <xsl:apply-templates select="key( Phase , Phase)[Master = ID]"/>
      </Phase>
   </xsl:template>

   <xsl:template match="Row" name="Row">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
         <xsl:apply-templates select="//Row[Phase=current()/Phase][Master=current()/ID][Master != ID]"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

在对XML样本适用时,产出如下:

<Rows>
   <Phase name="Initiation">
      <Row>
         <ProjectID>1000</ProjectID>
         <Phase>Initiation</Phase>
         <ID>1</ID>
         <Name>Work item 1</Name>
         <Master>1</Master>
         <Row>
            <ProjectID>1000</ProjectID>
            <Phase>Initiation</Phase>
            <ID>2</ID>
            <Name>Work item 2</Name>
            <Master>1</Master>
         </Row>
      </Row>
   </Phase>
   <Phase name="Closing">
      <Row>
         <ProjectID>1000</ProjectID>
         <Phase>Closing</Phase>
         <ID>3</ID>
         <Name>Work item 3</Name>
         <Master>3</Master>
         <Row>
            <ProjectID>1000</ProjectID>
            <Phase>Closing</Phase>
            <ID>4</ID>
            <Name>Work item 4</Name>
            <Master>3</Master>
            <Row>
               <ProjectID>1000</ProjectID>
               <Phase>Closing</Phase>
               <ID>5</ID>
               <Name>Work item 5</Name>
               <Master>4</Master>
            </Row>
         </Row>
      </Row>
   </Phase>
</Rows>

如果你想要产出超文本,将尝试以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" indent="yes"/>
   <xsl:key name="Phase" match="Row" use="Phase"/>

   <xsl:template match="/">
      <body>
         <xsl:apply-templates select="//Row[generate-id() = generate-id(key( Phase , Phase)[1])]" mode="first"/>
      </body>
   </xsl:template>

   <xsl:template match="Row" mode="first">
      <h1>
         <xsl:value-of select="Phase"/>
      </h1>
      <ul>
         <xsl:apply-templates select="key( Phase , Phase)[Master = ID]"/>
      </ul>
   </xsl:template>

   <xsl:template match="Row" name="Row">
      <li>
         <xsl:value-of select="Name"/>
         <xsl:if test="//Row[Phase=current()/Phase][Master=current()/ID][Master != ID]">
            <ul>
               <xsl:apply-templates select="//Row[Phase=current()/Phase][Master=current()/ID][Master != ID]"/>
            </ul>
         </xsl:if>
      </li>
   </xsl:template>
</xsl:stylesheet>

This should output the following HTML

<body>
   <h1>Initiation</h1>
   <ul>
      <li>Work item 1
         <ul>
            <li>Work item 2</li>
         </ul>
      </li>
   </ul>
   <h1>Closing</h1>
   <ul>
      <li>Work item 3
         <ul>
            <li>Work item 4
               <ul>
                  <li>Work item 5</li>
               </ul>
            </li>
         </ul>
      </li>
   </ul>
</body>
问题回答

暂无回答




相关问题
When test hanging in an infinite loop

I m tokenising a string with XSLT 1.0 and trying to prevent empty strings from being recognised as tokens. Here s the entire function, based on XSLT Cookbook: <xsl:template name="tokenize"> ...

quick xslt for-each question

Let s say I have an XML document that has this: <keywords> <keyword>test</keyword> <keyword>test2</keyword> <keyword>test3</keyword> <keyword>test4</...

XSLT Transform XML with Namespaces

I m trying to transform some XML into HTML using XSLT. Problem: I can t get it to work. Can someone tell me what I m doing wrong? XML: <ArrayOfBrokerage xmlns:i="http://www.w3.org/2001/...

XSLT output to HTML

In my XSLT file, I have the following: <input type="button" value= <xsl:value-of select="name">> It s an error as it violates XML rule. What I actually want is having a value from an ...

Mangling IDs and References to IDs in XML

I m trying to compose xml elements into each other, and the problem I am having is when there s the same IDs. Basically what I need to do is mangle all the IDs in an xml file, as well as the ...

Sharepoint 2007 Data view Webpart custom parameters

I m sort of new to the custom parameters that can be setup on a DataView Webpart. There are 6 options: - None - Control - Cookie - Form - QueryString - Server Variable I think that None, Cookie and ...