【问题标题】:XSLT 1.0: Surrounded tag with following-sibling conditionsXSLT 1.0:具有以下兄弟条件的环绕标记
【发布时间】:2019-08-22 11:50:57
【问题描述】:

当它们直接跟随兄弟姐妹时,我尝试用标签作者:(姓氏和名字)标签包围。如果没有以这种方式排序,则直接将标签(名字或姓氏)包围。此标签由特定属性 (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>

请注意,此帖子遵循以前的票证:(xslt transform and lxml python problem to handle namespace。提前感谢您的帮助。

【问题讨论】:

    标签: xml python-3.x xslt-1.0 lxml


    【解决方案1】:

    这很难理解。如果我确实正确理解了所需的逻辑,那么在 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 属性。

    【讨论】:

    • 感谢您的回答。你在 XSLT1.0 中是对的,这并不容易,但我使用 lxml 库,它不处理 XSLT2.0。不幸的是,改变给定规则是不可能的,只有属性 bilbo 是一个特定的标记。
    • @Mikael.hork257k,请注意,如果您将标签与属性 bilbo 混合,而没有 as Amblard Mathieu 你的 xsl 提案得到了错误的结果。
    • @mathieu 如果这是个问题,请将 [@bilbo] 谓词添加到以下兄弟节点。
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-16
    • 2015-12-08
    相关资源
    最近更新 更多