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

xsl:当两个节点相等时,显示第一个节点的子节点

  •  1
  • Vanessa  · 技术社区  · 6 年前

    我使用的是XML编辑器19.1,Saxon P.E 9.7。

    对于每个选定的 div ,我希望显示 graphic/@url ,紧随其后 <surface> 如果 surface/@xml:id = div/@facs

    XSL

     <xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
      <xsl:variable name="div4tablet" select="@facs"/>
       <xsl:choose>
        <xsl:when test="translate(.[@n]/$div4tablet, '#', '') = preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n]/@xml:id">
         <xsl:value-of select=""/> <!-- DISPLAY graphic/@url that follows facsimile/surfaceGrp/surface -->
        </xsl:when>
        <xsl:otherwise/>
       </xsl:choose>
      [....]
     </xsl:for-each> 
    

    TEI 实例

     <facsimile>     
      <surfaceGrp n="1" type="tablet">
       <surface n="1.1" xml:id="ktu1-2_i_1_to_10_img">
        <graphic url="../img/KTU-1-2-1-10-recto.jpg"/>
        <zone xml:id=""/>
        <zone xml:id=""/>
       </surface>
        <surface n="1.2" xml:id="ktu1-2_i_10_to_30_img">
        <graphic url="../img/KTU-1-2-10-30-recto.jpg"/>
        <zone xml:id=""/>
       </surface>
       [...]
      </surfaceGrp>
      <surfaceGrp n="2">
      [...]
      </surfaceGrp>
     </facsimile>
    
    
     <text>
      [...]
      <div3 type="col">
       <div4 n="1.2.1-10" xml:id="ktu1-2_i_1_to_10" facs="#ktu1-2_i_1_to_10_img">
        [...]
       </div4>
       <div4 n="1.2.10-30" xml:id="ktu1-2_i_10_to_30" facs="#ktu1-2_i_10_to_30_img">
        [...]
       </div4>
      </div3>
     </text> 
    

    我试过了 <xsl:value-of select="preceding::facsimile/surfaceGrp[@type='tablet']/surface[@n, @xml:id]/graphic/@url"/> ,但它显示所有 图形/@url 不仅是接下来的 fascsimile/surfaceGrp/surface 。 所以我的问题是:如何仅显示 surface/graphic/@url 对于每个 div3[@type='col']/div4[@n] ?

    首先,感谢您的善意帮助。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Martin Honnen    6 年前

    使用XSLT 2或3时,元素具有 xml:id 属性您甚至不需要密钥,但可以使用 id 功能:

      <xsl:template match="div4">
          <div>
              <xsl:value-of select="id(substring(@facs, 2))/graphic/@url"/>
          </div>
      </xsl:template>
    

    我把 身份证件 到与 div4 元素,但您当然可以在 for-each 选择这些元素。

    请参阅 https://xsltfiddle.liberty-development.net/bdxtpR

        2
  •  3
  •   Joel M. Lamsen    6 年前

    您应该使用 xsl:key 对于此类问题。

    首先,我们必须为目标节点声明一个密钥

    <xsl:key name="kSurface" match="surface" use="concat('#', @xml:id)"/>
    

    请注意 concat 函数在此处使用时,将#添加到xml:id中,以便键显示为:

    #ktu1-2_i_1_to_10_img
    #ktu1-2_i_10_to_30_img
    

    现在在这个循环中:

    <xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
    

    我们可以访问与 @facs 具有以下属性:

     <xsl:value-of select="key('kSurface', @facs)/graphic/@url"/>
    

    整个样式表如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="1.0">
    
        <xsl:output omit-xml-declaration="yes"/>
    
        <xsl:key name="kSurface" match="surface" use="concat('#', @xml:id)"/>
    
        <xsl:template match="/">
            <xsl:for-each select="descendant-or-self::div3[@type='col']/div4[@n]">
                <xsl:value-of select="key('kSurface', @facs)/graphic/@url"/>
                <xsl:text>&#xA;</xsl:text>
            </xsl:for-each> 
        </xsl:template>
    
    </xsl:stylesheet>
    

    在行动中看到它 here

    推荐文章