代码之家  ›  专栏  ›  技术社区  ›  Lilleman

如何基于与我正在搜索的树中的属性具有相同名称的属性,在循环中获得xpath的XML节点?

  •  1
  • Lilleman  · 技术社区  · 14 年前

    我真的无法更好地表述这一点,所以我将用一个例子来代替:

    XML格式:

    <root>
      <foo>
        <bar id="1">sdf</bar>
        <bar id="2">sdooo</bar
      </foo>
      <feng>
        <heppa id="4">hihi</heppa>
        <heppa id="2">sseeapeea</heppa>
        <heppa id="1">....</heppa>
      </feng>
    </root>
    

    XSLT:

    <xsl:for-each select="/root/foo/bar">
      <p>
        <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = @id]" />
      </p>
    </xsl:for-each>
    

    期望输出:

    <p>sdf: ....</p>
    <p>sdooo: sseeapeea</p>
    

    实际输出:

    <p>sdf: hihi</p>
    <p>sdooo: hihi</p>
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   user357812 user357812    14 年前

    对于仅使用XPath 1.0选择节点,需要进行节点集比较:

    /root/feng/heppa[@id=/root/foo/bar/@id]
    

    当然,这有NxM的复杂性(与其他XSLT解决方案一样)

    对于XSLT 1.0,您应该使用键,因为存在交叉引用:

    <xsl:key name="kBarById" select="bar" use="@id"/>
    
    <xsl:template match="/root/feng/heppa[key('kBarById',@id)]">       
        <p>       
            <xsl:value-of select="concat(key('kBarById',@id),': ',.)"/>
        </p>       
    </xsl:template> 
    
        2
  •  2
  •   Jon Hanna    14 年前

    /root/foo/bar 自从 /root/foo

    你在比较 @id 当然,对于第一个被检查的节点也是如此。你可以用 current() 要在表达式中引用当前节点,请执行以下操作:

    <xsl:for-each select="/root/foo/bar">
      <p>
        <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = current()/@id]" />
      </p>
    </xsl:for-each>
    
        3
  •  1
  •   jasso    14 年前

    另一个解决办法是阅读 id 属性转换为变量。

    <xsl:for-each select="/root/foo/bar">
        <xsl:variable name="id" select="@id"/>
        <p>
            <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = $id]" />
        </p>
    </xsl:for-each>
    

    如果您的实际用例更复杂,并且您需要使用 身份证件 每一节都有多次。