How do I retrieve a sibling by tag name in XSLT?

2020-03-29 02:45发布

I am having an issue with the following, I need the ID to be of each promotiom:

Here is my XML:

 <Promotions>
      <Promotion>
        <Category>Arts &amp; Entertainment</Category>
        <Client>Client 1</Client>
        <ID>2</ID>
        <Title>Get your Free 2</Title>
      </Promotion>
      <Promotion>
        <Category>Client 1</Category>
        <Client>Artsquest</Client>
        <ID>4</ID>
        <Title>Get your Free 4</Title>
      </Promotion>
      <Promotion>
        <Category>Client 1</Category>
        <Client>Artsquest</Client>
        <ID>5</ID>
        <Title>Get your Free 5</Title>
      </Promotion>
      <Promotion>
        <Category>Community &amp; Neighborhood</Category>
        <Client>Client 2</Client>
        <ID>1</ID>
        <Title>Get your Free 1</Title>
      </Promotion>
      <Promotion>
        <Category>Education</Category>
        <Client>Client 3</Client>
        <ID>3</ID>
        <Title>Get Your Free 3</Title>
      </Promotion>
      <Promotion>
        <Category>Home &amp; Garden</Category>
        <Client>Client 4</Client>
        <ID>6</ID>
        <Title>Get your Free 6</Title>
      </Promotion>
    </Promotions>

Here is my XSLT file:

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


      <xsl:output method="html" indent="yes" /> 

      <xsl:key name="categories" match="Category" use="." /> 
      <xsl:key name="client" match="Client" use="." /> 
      <xsl:key name="title" match="Title" use="." /> 

      <xsl:template match="/"> 
        <ul id="red" class="treeview-red"> 
          <xsl:for-each select="/Promotions/Promotion/Category[  
                    generate-id(.) = generate-id(key('categories', .)[1])  
                    ]">
          <li>
        <span>
          <xsl:value-of select="."/> 
        </span>

        <ul> 
          <xsl:call-template name="category-client"> 
            <xsl:with-param name="category" select="."/> 
          </xsl:call-template> 
        </ul>
      </li>

          </xsl:for-each>
        </ul>
      </xsl:template> 

      <xsl:template name="category-client"> 
        <xsl:param name="category" /> 
        <xsl:for-each select="/Promotions/Promotion[Category=$category]/Client[  
                    generate-id(.) = generate-id(key('client', .)[1]) 
                    ]">
          <li>
            <span>
              <xsl:value-of select="."/>
            </span>
            <ul>
              <xsl:call-template name="category-client-title">
                <xsl:with-param name="category" select="$category"/>
                <xsl:with-param name="client" select="."/>
              </xsl:call-template>
            </ul>
          </li>
        </xsl:for-each> 
      </xsl:template> 

      <xsl:template name="category-client-title"> 
        <xsl:param name="category" /> 
        <xsl:param name="client" /> 
        <xsl:for-each select="/Promotions/Promotion[Category=$category]/Title[  
                    generate-id(.) = generate-id(key('title', .)[1]) 
                    ]"> 
          <li> 
        <span>
          <asp:LinkButton ID ="{/Promotions/Promotion[Category=$category]/ID}" onclick="LinkClicked">

        <xsl:value-of select="."/>
         </asp:LinkButton>
        </span> 
          </li> 

        </xsl:for-each>

      </xsl:template>

    </xsl:stylesheet> 

My issue is that the ID outputted if the client has multiple promotions in a category, I only get the first ID and it repeats for each, what is the best way to change this so that the ID matches the row the promotion title is coming from?

here is the output I am speaking of,I am so not grasping xsl...

 <ul id="red" class="treeview-red" xmlns:asp="remove">
  <li><span>Arts &amp; Entertainment</span><ul>
      <li><span>Client 1</span><ul>
          <li><span><asp:LinkButton ID="2" onclick="LinkClicked">Get your Free 2</asp:LinkButton></span></li>
          <li><span><asp:LinkButton ID="2" onclick="LinkClicked">Get your Free 4</asp:LinkButton></span></li>
          <li><span><asp:LinkButton ID="2" onclick="LinkClicked">Get your Free 5</asp:LinkButton></span></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><span>Community &amp; Neighborhood</span><ul>
      <li><span>Client 2</span><ul>
          <li><span><asp:LinkButton ID="1" onclick="LinkClicked">Get your Free 1</asp:LinkButton></span></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><span>Education</span><ul>
      <li><span>Client 3</span><ul>
          <li><span><asp:LinkButton ID="3" onclick="LinkClicked">Get Your Free 3</asp:LinkButton></span></li>
        </ul>
      </li>
    </ul>
  </li>
  <li><span>Home &amp; Garden</span><ul>
      <li><span>Client 4</span><ul>
          <li><span><asp:LinkButton ID="6" onclick="LinkClicked">Get your Free 6</asp:LinkButton></span></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

标签: xslt
3条回答
forever°为你锁心
2楼-- · 2020-03-29 03:01

Try something like position()=1 in your XSLT to select the first occurrence.

查看更多
Anthone
3楼-- · 2020-03-29 03:09

Just change

<asp:LinkButton ID ="{/Promotions/Promotion[Category=$category]/ID}" onclick="LinkClicked">

to

<asp:LinkButton ID ="{../ID}" onclick="LinkClicked">
查看更多
趁早两清
4楼-- · 2020-03-29 03:26

The correct XPath in this situation is:

<asp:LinkButton ID ="{../ID}" onclick="LinkClicked">

Since you are in <Title> context within the <xsl:for-each>, you must go up one level and fetch the <ID> from there. Your try

/Promotions/Promotion[Category=$category]/ID

fetches all <Promotion>s of a certain category and takes the first ID from the bunch, which is the same every time, naturally.

查看更多
登录 后发表回答