XSLT 1.0:带有以下兄弟条件的包围标记

XSLT 1.0: Surrounded tag with following-sibling conditions

当他们直接跟随兄弟姐妹时,我尝试用标签 author : (surname and forename) 标签包围。如果不是以这种方式排序,则直接将标签(名字或姓氏)包围起来。此标记由特定属性 (bilbo) 指定。所有标签都有一个默认的命名空间,我需要使用 XSLT 1.0。

这是我的 xml 输入。

<TEI xmlns="http://www.tei-c.org/ns/1.0">
<surname> Amblard </surname>
      <bibl>
          <surname bilbo="True"> Amblard </surname>
          <forename bilbo="True"> F. </forename>
          <c bilbo="True"> , </c>
          <forename bilbo="True"> P. </forename>
          <title>titre</title>
          <surname bilbo="True"> Amblard </surname>
  </bibl>
</TEI>

这是我的 xsl 文件:

<?xml version = "1.0" encoding = "UTF-8"?> 
<xsl:stylesheet version = "1.0" 
   xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"   
   xmlns:tei = "http://www.tei-c.org/ns/1.0">   
   <xsl:template match = "@*|node()"> 
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
   </xsl:template>
   <xsl:template match="tei:surname[@bilbo]">
    <xsl:element name="author" namespace="http://www.tei-c.org/ns/1.0">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
        <xsl:if test="following-sibling::*[1][self::forename and @bilbo]">
            <xsl:copy-of select="following-sibling::*[1]"/>
        </xsl:if>
    </xsl:element>
   </xsl:template>
   <xsl:template match="tei:forename[@bilbo]">
    <xsl:if test="not(preceding-sibling::*[1][self::surname and @bilbo])">
        <xsl:element name="author" namespace="http://www.tei-c.org/ns/1.0">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:element>
    </xsl:if>
   </xsl:template>
</xsl:stylesheet>

输出为:

<TEI xmlns="http://www.tei-c.org/ns/1.0">
   <surname> Amblard </surname>
      <bibl>
          <author>
         <surname bilbo="True"> Amblard </surname>
      </author>
          <author>
         <forename bilbo="True"> F. </forename>
      </author>
          <c bilbo="True"> , </c>
          <author>
         <forename bilbo="True"> P. </forename>
      </author><title>titre</title>
          <author>
     <surname bilbo="True"> Amblard </surname>
  </author>
  </bibl>
</TEI>

但预期的输出应该是:

<TEI xmlns="http://www.tei-c.org/ns/1.0">
   <surname> Amblard </surname>
      <bibl>
          <author>
         <surname bilbo="True"> Amblard </surname>
         <forename bilbo="True"> F. </forename>
      </author>
          <c bilbo="True"> , </c>
          <author>
         <forename bilbo="True"> P. </forename>
      </author><title>titre</title>
          <author>
     <surname bilbo="True"> Amblard </surname>
  </author>
  </bibl>
</TEI>

请注意,此 post 遵循之前的票证:(xslt transform and lxml python problem to handle namespace。在此先感谢您的帮助。

这个比较难理解。而且,如果我确实正确理解了所需的逻辑,那么在 XSLT 1.0:

中执行大量工作
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tei="http://www.tei-c.org/ns/1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- leading surname -->
<xsl:template match="tei:surname[@bilbo][following-sibling::*[1][self::tei:forename]]" priority="1">
     <xsl:element name="author" namespace="http://www.tei-c.org/ns/1.0">
        <xsl:copy-of select=". | following-sibling::tei:forename[1][@bilbo]"/>
     </xsl:element>
</xsl:template>

<!-- leading forename -->
<xsl:template match="tei:forename[@bilbo][following-sibling::*[1][self::tei:surname]]" priority="1">
     <xsl:element name="author" namespace="http://www.tei-c.org/ns/1.0">
        <xsl:copy-of select=". | following-sibling::tei:surname[1][@bilbo]"/>
     </xsl:element>
</xsl:template>

<!-- surname or forename, standalone -->
<xsl:template match="tei:surname[@bilbo] | tei:forename[@bilbo]">
     <xsl:element name="author" namespace="http://www.tei-c.org/ns/1.0">
        <xsl:copy-of select="."/>
     </xsl:element>
</xsl:template>

<!-- trailing surname -->
<xsl:template match="tei:surname[@bilbo][preceding-sibling::*[1][self::tei:forename]]"/>

<!-- trailing forename -->
<xsl:template match="tei:forename[@bilbo][preceding-sibling::*[1][self::tei:surname]]"/>

</xsl:stylesheet>

也许使用同级递归来解决这个问题会更简单。但这将意味着更改给定规则,将逻辑应用于 bibl 父级中的 surnames 和 forenames,而不是使用 bilbo 属性。