在xsl中的for-each循环中时

时间:2019-05-24 07:23:25

标签: xslt xslt-1.0 xslt-2.0 xslt-grouping xslt-3.0

我有一个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元素的值。而我们必须通过将名称元素值与xpath //root/profiles/profile进行比较来获取Gender元素的值。当我使用下面的代码

  <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>

当返回第二个元素的循环遍历时,我得到了第一个元素的相应性别值,返回的第一个元素的值与两个xxx相同,yyy,性别返回为“男性”。有人检查此代码,让我知道此问题的任何解决方法

2 个答案:

答案 0 :(得分:0)

我将使用 key 从相应的配置文件中查找数据-说:

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>

答案 1 :(得分:0)

如@ 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>