2017-01-26 39 views
1

我的研究項目,我在XML這個文件/ TEIXSL的for-each空間分隔的屬性值

<TEI xmlns="http://www.tei-c.org/ns/1.0" > 
<body> 
    <div> 
     <p> 
      <span target="#" type="passage" ana="Tag957 Tag874"> 
       <span target="#" ana=""/> 
      </span> 
      <seg><date when="1980-01-01" type="date_seg"/>blabla blabla 
       blabla blablablabla blablablabla blablablabla blablablabla bl 
      </seg> 
      <span target="#" type="passage" ana="Tag1657 "> 
       <span target="#" ana=""/> 
      </span> 
      <seg><date from="1980-01-03" to="1980-01-05" type="date_seg"/>blabla 
      </seg> 
     </p> 
    </div> 
</body> 
</TEI> 

我需要提取包含在跨越每個標籤/ @語錄:日期和以下節點seg的字符串長度。如果我們計算日期屬性@from或@to,我只需要@from的值。 我需要看起來像:

Tag957;1980-01-01;88 
Tag874;1980-01-01;88 
Tag1657;1980-01-03;11 

我想這一點,但我不知道怎麼換每次在一個時間applyed一個屬性值表達

<xsl:template match="tei:p"> 
     <xsl:for-each select="tei:span"> 
       <xsl:value-of select="./@ana"/> 
       <xsl:text>;</xsl:text> 
      <xsl:if test="following-sibling::tei:seg/tei:date/@from or following-sibling::tei:seg/tei:date/@to"> 
       <xsl:value-of select="following-sibling::tei:seg/tei:date/@from"/> 
      </xsl:if> 
      <xsl:if test="following-sibling::tei:seg/tei:date/@when"> 
       <xsl:value-of select="following-sibling::tei:seg/tei:date/@when"/> 
      </xsl:if> 
       <xsl:text>;</xsl:text> 
       <xsl:value-of select="string-length(following-sibling::tei:seg)"/> 
       <xsl:text>;</xsl:text> 
       <xsl:value-of select="$newLine"/> 
     </xsl:for-each> 
</xsl:template> 
+1

哪個XSLT處理器,XSLT版本做你用/你可以用嗎? –

+0

我在Oxygen軟件中使用XSLT處理器,我選擇的是Saxon-HE9.6.0.7 –

回答

2

使用XSLT 2.0,您可以使用tokenize識別屬性值不同的值,那麼你可以在http://xsltransform.net/jz1PuPL重寫代碼爲

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="http://www.tei-c.org/ns/1.0"> 
    <xsl:template match="p"> 
     <xsl:for-each select="span"> 
      <xsl:variable name="span" select="."/> 
      <xsl:for-each select="tokenize(@ana, '\s+')[normalize-space()]"> 
       <xsl:value-of select="."/> 
       <xsl:text>;</xsl:text> 
       <xsl:if test="$span/following-sibling::seg[1]/date/@from or $span/following-sibling::seg[1]/date/@to"> 
       <xsl:value-of select="$span/following-sibling::seg[1]/date/@from"/> 
       </xsl:if> 
       <xsl:if test="$span/following-sibling::seg/date/@when"> 
       <xsl:value-of select="$span/following-sibling::seg/date/@when"/> 
       </xsl:if> 
       <xsl:text>;</xsl:text> 
       <xsl:value-of select="string-length($span/following-sibling::seg[1])"/> 
       <xsl:text>;</xsl:text> 
       <xsl:value-of select="'&#10;'"/> 
      </xsl:for-each>  
     </xsl:for-each> 
    </xsl:template> 
</xsl:transform> 

在線。

+0

謝謝,它在我給的XML上運行良好。我在我的其他文件上測試了它,並且必須在第二個xsl中添加seg [1]:如果導致它檢索所有其他兄弟的日期seg –

3

你對於span元素只做了單環。這不夠。

實際上,對於每個這樣的span你必須:

  • 閱讀ana屬性。
  • 使用空格(如果可以的話,使用XSLT 2.0,它具有此功能)令其變形。

對於每個結果令牌(不是爲@ana整個價值),你必須進行內部for-each循環:

  • 查找只有第一以下seg兄弟及其子date元素: select="following-sibling::tei:seg[1]/tei:date"(注意,我加了[1])。
  • 檢查它是否包含必需的屬性(from,towhen)。

如果確實如此,那麼:

  • 打印從目前ana屬性提取當前令牌。
  • 根據您的需要打印需要的日期(從當前的date元素開始)。
  • 打印要打印的東西的其餘部分。

這只是一個草圖,我省略了保留兩個循環中的當前值在各個變量中的細節。

我希望它能幫助您達到最終結果。

1

XSLT-1。0

我創建了一個遞歸模板來標記化ana屬性中的值,併爲每個跨度調用它。我不得不在第8行添加一個空格爲模板的工作: <xsl:with-param name="remaining-ana-val" select="substring-after(concat(./@ana,' '),' ')"/>

<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="text" omit-xml-declaration="yes" encoding="UTF-8"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="tei:p"> 
     <xsl:for-each select="tei:span"> 
      <xsl:call-template name="recurse_ana"> 
       <xsl:with-param name="ana_val" select="substring-before(./@ana,' ')"/> 
       <xsl:with-param name="remaining-ana-val" select="substring-after(concat(./@ana,' '),' ')"/> 
       <xsl:with-param name="seg" select="following-sibling::tei:seg[1]"/> 
      </xsl:call-template> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template name="recurse_ana"> 
     <xsl:param name="ana_val"/> 
     <xsl:param name="remaining-ana-val"/> 
     <xsl:param name="seg"/> 
     <xsl:if test="string-length($ana_val) > 0"><xsl:value-of select="$ana_val"/> 
      <xsl:value-of select="';'"/> 
      <xsl:value-of select="$seg/tei:date/(@when|@from)"/> 
      <xsl:value-of select="';'"/> 
      <xsl:value-of select="string-length($seg)"/> 
      <xsl:value-of select="'&#x0D;'"/> 
      <xsl:call-template name="recurse_ana"> 
       <xsl:with-param name="ana_val" select="substring-before($remaining-ana-val,' ')"/> 
       <xsl:with-param name="remaining-ana-val" select="substring-after($remaining-ana-val,' ')"/> 
       <xsl:with-param name="seg" select="$seg"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

Tag957;1980-01-01;105 
Tag874;1980-01-01;105 
Tag1657;1980-01-03;19 

在線鏈接:分別http://xsltransform.net/gWEamLJ/2

+0

感謝您的建議。我在其他文件上測試過它,但它似乎只處理@ana中具有多個值的跨度,而不是僅具有一個值的跨度。奇怪的是:-) –

+0

@ r.let樣例XML中的第二個跨度在'ana'屬性內有額外的空間。我利用它來標記屬性值。也許其他'span'沒有這個額外的屬性,因此被排除在外。 – Madeyedexter