Когда внутри для каждого цикла в XSL - PullRequest
0 голосов
/ 24 мая 2019

У меня есть xml, который имеет одинаковые элементы на 2 разных уровнях. Мне нужно сравнить значение элементов на 2 уровнях и вернуть значение соответствующего элемента.Например, у меня есть следующий xml

<root>
  <profiles>
    <profile>
     <Name>xxx</Name>
     <Gender>Male</Gender>
    </profile>
    <profile>
     <Name>yyy</Name>
     <Gender>Female</Gender>
    </profile>
  </profiles>
  <subroot>
    <profiles>
      <profile>
       <sName>xxx</sName>
       <sAge>10</sAge>
      </profile>
      <profile>
       <sName>yyy</sName>
       <sAge>20</sAge>
      </profile>
    </profiles>
  </subroot>
</root>

. Мне нужно поставить цикл для //root/subroot/profiles/profile и получить значение Name,Age,Gender элементов.Принимая во внимание, что мы должны взять значение элемента Gender, сравнивая значение элемента name с xpath //root/profiles/profile.Когда я использую приведенный ниже код

  <xsl:for-each select="//root/subroot/profiles/profile">
    <xsl-for-each select="//root/profiles/profile">
      <xsl:choose>
       <xsl:when name=sname>
        <xsl:value-of select="Gender">
       </xsl:when>
      </xsl:choose>
    <xsl:for-each>
  </xsl-for-each>

, я получаю соответствующее значение пола для 1-го элемента, когда при обходе цикла для 2-го элемента возвращается то же значение 1-го элемента, что и для xxx, yyy Пол возвращаетсякак «мужской».Кто-то проверил этот код и дал мне знать, как решить эту проблему

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Многие запросы на объединение лучше всего решать с помощью ключа, как описано в @ michael.hor257k, но более общий подход заключается в связывании переменных:

<xsl:for-each select="//root/subroot/profiles/profile">
  <xsl:variable name="outer-profile" select="."/>
  <xsl-for-each select="//root/profiles/profile">
     <xsl:variable name="inner-profile" select="."/>
      <xsl:choose>
       <xsl:when test="$outer-profile/x/y/z = $inner-profile/p/q/r">
        ...
       </xsl:when>
      </xsl:choose>
    <xsl:for-each>
  </xsl-for-each>
0 голосов
/ 24 мая 2019

Я бы использовал ключ для поиска данных из соответствующего профиля - скажем:

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:strip-space elements="*"/>

<xsl:key name="subprofile" match="profile" use="sName" />

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each select="profiles/profile">
            <xsl:copy>
                <xsl:copy-of select="*"/>
                <xsl:copy-of select="key('subprofile', Name)/sAge"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

или, если вы предпочитаете другое направление:

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:strip-space elements="*"/>

<xsl:key name="profile" match="profile" use="Name" />

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each select="subroot/profiles/profile">
            <xsl:copy>
                <xsl:copy-of select="key('profile', sName)/*"/>
                <xsl:copy-of select="sAge"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

В обоих случаях результат будет:

Результат

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <profile>
    <Name>xxx</Name>
    <Gender>Male</Gender>
    <sAge>10</sAge>
  </profile>
  <profile>
    <Name>yyy</Name>
    <Gender>Female</Gender>
    <sAge>20</sAge>
  </profile>
</root>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...