有条件地匹配当前节点值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有条件地匹配当前节点值相关的知识,希望对你有一定的参考价值。
给出以下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>
答案
我定义了一个为人们编制索引的键:
<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>
另一答案
你想要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>
另一答案
如果您需要访问多个用户,那么JeniT's <xsl:key />
approach是理想的选择。
以下是我的另类选择:
<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>
(错字)结尾
如果我们知道XML文档的整体结构(具有根节点等),则可以给出更好的解决方案。
另一答案
我认为他真正想要的是匹配“当前”节点,而不是人员节点中的匹配:
<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>
另一答案
只是为了将我的想法添加到堆栈中
<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]”来约束第一个人祖先。
以上是关于有条件地匹配当前节点值的主要内容,如果未能解决你的问题,请参考以下文章