Добавление атрибутов от узла к родительскому

#xslt

Вопрос:

Прочитав уже много об этом вопросе, я все еще не нахожу окончательного решения своей проблемы, так как я абсолютный новичок в xsl.

Я хочу добавить все атрибуты дочерних узлов на родительский уровень.

Это то, что у меня есть:

  <rankings date="2021-03-15">
<ranking rank="1" rank_change="0" points="12008">
  <player initials="" nationality="SRB" last_name="Djokovic" first_name="Novak" id="7" display_name="Novak Djokovic"/>
</ranking>
<ranking rank="2" rank_change="1" points="9940">
  <player initials="" nationality="RUS" last_name="Medvedev" first_name="Daniil" id="35844" display_name="Daniil Medvedev"/>
</ranking>
<ranking rank="3" rank_change="-1" points="9670">
  <player initials="" nationality="ESP" last_name="Nadal" first_name="Rafael" id="4" display_name="Rafael Nadal"/>
</ranking>
</rankings>
 

Это то, что я пробовал (думаю, я пропустил передачу личности)

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="rankings">
    <data>
      <xsl:apply-templates select="*"/>
    </data>
  </xsl:template>

 <xsl:template match="ranking | player">
    <row>
        
        <xsl:apply-templates select="@* | node()"/>
        
    </row>
  </xsl:template>


  <xsl:template match="ranking/@* | player/@*">
    <xsl:element name="{name(.)}">
    <xsl:value-of select="."/>
    </xsl:element>  
  </xsl:template>
  
</xsl:stylesheet>
 

Со следующим результатом:

 <data>
    <row>
       <rank>1</rank>
       <rank_change>0</rank_change>
       <points>12008</points>
       <row>
           <initials/>
           <nationality>SRB</nationality>
           <last_name>Djokovic</last_name>
           <first_name>Novak</first_name>
           <id>7</id>
          <display_name>Novak Djokovic</display_name>
     </row>
</row>
</data>
 

Это моя цель:

 <data>
    <row>
       <rank>1</rank>
       <rank_change>0</rank_change>
       <points>12008</points>
       <initials/>
       <nationality>SRB</nationality>
       <last_name>Djokovic</last_name>
       <first_name>Novak</first_name>
       <id>7</id>
       <display_name>Novak Djokovic</display_name>
</row>
</data>
 

Я надеюсь, что один из вас сможет мне в этом помочь.

Твое здоровье, Фил

Комментарии:

1. Результат, который вы показываете, не является результатом, который я получаю при запуске вашего кода. Что еще более важно, неясно, каким должен быть результат: почему Медведев и Надаль исключены из вашего «голевого» результата?

Ответ №1:

попробуйте разделить рейтинг и игрока в своем собственном шаблоне

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

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

Результат:

 <data>
   <row>
      <rank>1</rank>
      <rank_change>0</rank_change>
      <points>12008</points>
      <initials/>
      <nationality>SRB</nationality>
      <last_name>Djokovic</last_name>
      <first_name>Novak</first_name>
      <id>7</id>
      <display_name>Novak Djokovic</display_name>
   </row>
   <row>
      <rank>2</rank>
      <rank_change>1</rank_change>
      <points>9940</points>
      <initials/>
      <nationality>RUS</nationality>
      <last_name>Medvedev</last_name>
      <first_name>Daniil</first_name>
      <id>35844</id>
      <display_name>Daniil Medvedev</display_name>
   </row>
   <row>
      <rank>3</rank>
      <rank_change>-1</rank_change>
      <points>9670</points>
      <initials/>
      <nationality>ESP</nationality>
      <last_name>Nadal</last_name>
      <first_name>Rafael</first_name>
      <id>4</id>
      <display_name>Rafael Nadal</display_name>
   </row>
</data>
 

Комментарии:

1. Я думал, что это будет так просто, но не сделал этого сам. Большое вам спасибо!

Ответ №2:

Если я правильно угадываю, какова ваша настоящая цель, вы могли бы просто:

XSLT 1.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:template match="rankings">
    <data>
        <xsl:for-each select="ranking">
            <row>
                <xsl:for-each select=".//@*">
                    <xsl:element name="{name(.)}">
                        <xsl:value-of select="."/>
                    </xsl:element>  
                </xsl:for-each>     
            </row>
        </xsl:for-each>
    </data>
</xsl:template>

</xsl:stylesheet>