xslt - 名称位于其他一些元素名称之中的第一个元素的 XPATH

标签 xslt xpath xpath-2.0

<choices>
   <sic  />
   <corr />
   <reg  />
   <orig />
</choices>

<choice>
   <corr>Red</corr>
   <sic>Blue</sic>
<choice>

我想选择 <choice> 中的第一个元素其名称与 <choices> 中任何元素的名称匹配.

如果 name(node-set) 返回名称列表而不仅仅是第一个节点的名称,我可以使用

select="choice/*[name() = name(choices/*)][1]"

但事实并非如此(至少在 1.0 中不是),所以我将名称连接到一个字符串中并使用 contains():

<xsl:variable name="choices.str">
    <xsl:for-each select="choices/*">
        <xsl:text> </xsl:text><xsl:value-of select="concat(name(),' ')"/>
    </xsl:for-each>
</xsl:variable>
<xsl:apply-templates select="choice/*[contains($choices.str,name())][1]"/>

并得到我想要的:

Red<corr>的值

有没有更直接的方法?

最佳答案

我。使用此 XPath 2.0 一行:

/*/choice/*[name() = /*/choices/*/name()][1]

根据以下 XML 文档计算此 XPath 表达式时(提供的文档,但已更正为格式良好的 XML 文档):

<t>
    <choices>
        <sic  />
        <corr />
        <reg  />
        <orig />
    </choices>
    <choice>
        <corr>Red</corr>
        <sic>Blue</sic>
    </choice>
</t>

选择了正确的元素:

<corr>Red</corr>

二. XSLT 1.0(无键!):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vNames">
  <xsl:for-each select="/*/choices/*">
   <xsl:value-of select="concat(' ', name(), ' ')"/>
  </xsl:for-each>
 </xsl:variable>

 <xsl:template match="/">
  <xsl:copy-of select=
  "/*/choice/*
         [contains($vNames, concat(' ', name(), ' '))]
           [1]"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(如上)时,将再次选择正确的元素(并复制到输出):

<corr>Red</corr>

三.使用按键:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

  <xsl:key name="kChoiceByName" match="choice/*"
   use="boolean(/*/choices/*[name()=name(current())])"/>

 <xsl:template match="/">
  <xsl:copy-of select="/*/choice/*[key('kChoiceByName', true())][1]"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(如上)时,会产生相同的正确结果:

<corr>Red</corr>

建议读者尝试了解这一切是如何“工作”的:)

关于xslt - 名称位于其他一些元素名称之中的第一个元素的 XPATH,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12850223/

相关文章:

python - 在 Python 中使用 selenium 从 <li> 项中提取文本

html - XPath选择文本,但某些部分除外

xml - 带有超棒字体的 jsTree 树中的节点图标

XML 不间断空格

c# - 使用 C# 在内存中进行 XSLT 转换

xml - VBScript从XML节点分配变量

xslt - 已设置属性的 Concat 参数

xml - 这两个 XQuery 之间有什么区别

xml - WSO2 中 Xpath 2.0 中 If/else 语句的使用

sql-server - 如何通过检查两个节点的值(包括需要进行包含(类似)比较的节点)来更新 sql server 中的 XML 列