8

给定以下 XML:

<current>
  <login_name>jd</login_name>
</current>
<people>
  <person>
    <first>John</first>
    <last>Doe</last>
    <login_name>jd</login_name>
  </preson>
  <person>
    <first>Pierre</first>
    <last>Spring</last>
    <login_name>ps</login_name>
  </preson>
</people>

如何从当前/登录匹配器中获取“John Doe”?

我尝试了以下方法:

<xsl:template match="current/login_name">
  <xsl:value-of select="../people/first[login_name = .]"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="../people/last[login_name = .]"/>
</xsl:template>
4

5 回答 5

10

我会定义一个键来索引人员:

<xsl:key name="people" match="person" use="login_name" />

在这里使用键只会保持代码的整洁,但如果您经常需要<person>根据<login_name>子元素检索元素,您可能会发现它有助于提高效率。

我有一个模板,它返回给定的格式化名称<person>

<xsl:template match="person" mode="name">
  <xsl:value-of select="concat(first, ' ', last)" />
</xsl:template>

然后我会做:

<xsl:template match="current/login_name">
  <xsl:apply-templates select="key('people', .)" mode="name" />
</xsl:template>
于 2008-09-15T12:42:47.997 回答
4

你想要的current()功能

<xsl:template match="current/login_name">
  <xsl:value-of select="../../people/person[login_name = current()]/first"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="../../people/person[login_name = current()]/last"/>
</xsl:template>

或更干净一点:

<xsl:template match="current/login_name">
  <xsl:for-each select="../../people/person[login_name = current()]">
    <xsl:value-of select="first"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="last"/>
  </xsl:for-each>
</xsl:template>
于 2008-09-15T09:14:22.613 回答
1

如果您需要访问多个用户,那么JeniT 的<xsl:key />方法是理想的。

这是我的替代方案:

<xsl:template match="current/login_name">
    <xsl:variable name="person" select="//people/person[login_name = .]" />
    <xsl:value-of select="concat($person/first, ' ', $person/last)" />
</xsl:template>

我们将所选<person>节点分配给一个变量,然后我们使用该concat()函数输出名字/姓氏。

您的示例 XML 中也存在错误。<person>节点错误地以( </preson>typo)结尾

如果我们知道 XML 文档的整体结构(包括根节点等),可以给出更好的解决方案

于 2008-09-16T22:18:31.583 回答
0

我认为他真正想要的是匹配中“当前”节点的替换,而不是人员节点中的匹配:

<xsl:variable name="login" select="//current/login_name/text()"/>

<xsl:template match="current/login_name">
<xsl:value-of select='concat(../../people/person[login_name=$login]/first," ", ../../people/person[login_name=$login]/last)'/>

</xsl:template>
于 2008-09-15T09:14:22.507 回答
0

只是为了将我的想法添加到堆栈中

<xsl:template match="login_name[parent::current]">
 <xsl:variable name="login" select="text()"/>
 <xsl:value-of select='concat(ancestor::people/child::person[login_name=$login]/child::first/text()," ",ancestor::people/child::person[login_name=$login]/child::last/text())'/>
</xsl:template>

我总是更喜欢在我的 XPath 中明确使用轴,更详细但更清晰的恕我直言。

根据其余 XML 文档的外观(假设这只是一个片段),您可能需要限制对“ancestor::people”的引用,例如使用“ancestor::people[1]”来限制第一个人祖先。

于 2008-09-15T10:09:50.313 回答