How to get username by tag name in XSLT?

I had a problem with the following: I need the identifier of each advertising campaign:

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 problem is that the identifier is displayed if the client has several promotions in the category, I get only the first identifier, and it repeats for each, what is the best way to change it so that the identifier matches the title bar comes from?

here is the result i'm talking about, i don't understand xsl like that ...

 <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>
+2
source share
3 answers

The correct XPath in this situation is:

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

Since you are in <Title>context in <xsl:for-each>, you must rise one level and get <ID>from there. Your attempt

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

<Promotion> , , .

+2

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

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

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

-1
source

Source: https://habr.com/ru/post/1733178/


All Articles