2016-06-14 20 views
1

我正在研究將XML(tei)文檔轉換爲HTML的XSLT。 目標是創建可以樣式顯示爲固定列的div。在整個xml文檔中選擇空的<cb>元素之間的所有節點,將每個選區用div div打包

在文檔中,列開頭由2個空元素(里程碑和cb)表示。 「里程碑」表示文本流中的列數現在等於n屬性。 「cb」表示列的開始,其n屬性表示其從左到右的順序。 「cb」標籤並不總是兄弟姐妹。

示例XML:

<p> 
    <milestone unit="column" n="2"/> 
    <cb n="1"/> 
    M. Dudley 
    <lb/> 
    H. E. Ernshimer 
    <lb/> 
    M. M. Cash 
    <lb/> 
    John Wheatly 
    <lb/> 
    Jno W. Cash 
    <lb/> 
    <cb n="2"/> 
    R. L. Wilson 
    <lb/> 
    R. B. Ratliff L.C.C. 
    <lb/> 
    G. D Watkins Clk 
    <lb/> 
    A. C. Mayes 
    <lb/> 
    <pb/> 
</p> 
<p> 
    <note place="left margin">Jury 1863 Nov.</note> 
    <lb/> 
    <cb n="1"/> 
    D C Mitchenssson 
    <lb/> 
    A. W. Forde, Tm P 
    <lb/> 
    L S Thomson 
    <lb/> 
    Louis Martin 
    <hi rend="sup">c</hi> 
    Casslin 
    <lb/> 
    E. M. Stevens 
    <lb /> 
    <cb n="2"/> 
    O Ross Baker Clk Caldwell County Court 
    <lb/> 
    N. Jones 
    <lb/> 
    S. W. M 
    <milestone unit="column" n="1"/> 
    <pb/> 
    <lb/> 
    John Garrett 
</p> 

期望下面的結果。帶班等於它們的前面里程碑的n屬性的div:

<div class="column 2"> 
    M. Dudley<br /> 
    H. E. Ernshimer<br /> 
    M. M. Cash<br /> 
    John Wheatly<br /> 
    Jno W. Cash<br /> 
    ... 
</div> 
<div class="column 2"> 
    R. L. Wilson<br /> 
    R. B. Ratliff L.C.C.<br /> 
    G. D Watkins Clk<br /> 
    A. C. Mayes<br /> 
    Jas Crenshaw<br /> 
</div> 

我怎麼能抓住每對CB標籤之間的所有內容,幷包裹在一個包含分區的內容?我試過的所有東西都會產生一系列嵌套的div。

+1

ypu意味着什麼_「cb」標籤並不總是兄弟姐妹._?他們並不總是_direct_兄弟姐妹? –

回答

0

我怎麼能抓住每對CB標籤之間的一切

我沒有看到你有一個cb對標籤包圍一列的內容 - 僅領先cb元素在頂部。

IIUC,你想要做這樣的事情:

XSLT 1.0

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

<xsl:key name="txt-by-col" match="text()" use="generate-id(preceding-sibling::cb[1])" /> 

<xsl:template match="/"> 
    <root> 
     <xsl:for-each select="//cb"> 
      <div class="column {preceding::milestone[1]/@n}"> 
       <xsl:for-each select="key('txt-by-col', generate-id())"> 
        <xsl:value-of select="." /> 
        <br/> 
       </xsl:for-each>  
      </div> 
     </xsl:for-each> 
    </root> 
</xsl:template> 

</xsl:stylesheet> 

不,這假定列中的所有文本節點是領先cb元素的兄弟姐妹。

0

我想出了一個可行的解決方案。可能不夠高雅,但它是爲我的目的而工作的。我會在這裏發帖,以防將來對其他人有用。

<!-- add a white space in empty milestone so it doesn't wrap around other elements --> 
<xsl:template match="tei:milestone"> 
    <xsl:variable name="milenum" select="@n" /> 
    <milestone> 
    <xsl:attribute name="n"> 
     <xsl:value-of select="$milenum" /> 
    </xsl:attribute> 
    <xsl:text> </xsl:text> 
    </milestone> 
</xsl:template> 

<!-- add a white space in empty cb so it doesn't wrap around other elements --> 
<xsl:template match="tei:cb"> 
    <xsl:variable name="num" select="@n" /> 
    <cb> 
     <xsl:attribute name="n"> 
     <xsl:value-of select="$num" /> 
     </xsl:attribute> 
     <xsl:text> </xsl:text> 
    </cb> 
</xsl:template> 

<!-- wrap content following cb elements in a div, with a class indicating the number of columns in the preceding milestone n attribute (if milestone n=2, then div class=column1of2 or div class=column2of2) --> 
<xsl:template match="tei:p[tei:cb]"> 
    <!-- to print text before the first milestone --> 
    <xsl:apply-templates select="node()[not(preceding::tei:milestone)]" /> 
    <xsl:for-each select="tei:cb"> 
     <xsl:variable name="count" select="position()" /> 
     <div> 
     <xsl:variable name="numberofcolumns" select="preceding::tei:milestone[1]/@n" /> 
     <xsl:variable name="n" select="@n" /> 
     <xsl:attribute name="class"> 
      <xsl:text>column</xsl:text> 
      <xsl:value-of select="$n" /> 
      <xsl:text>of</xsl:text> 
      <xsl:value-of select="$numberofcolumns" /> 
     </xsl:attribute> 
     <xsl:apply-templates select="following-sibling::node()[preceding-sibling::tei:cb[1][@n=$n] and count(preceding-sibling::tei:cb)=$count and preceding::tei:milestone[1][@n>1] and not(self::tei:milestone)]" /> 
     </div> 
    </xsl:for-each> 
</xsl:template> 

此輸出:

<milestone n="2"> </milestone> 
<div class="column1of2"> 
</div> 
<div class="column2of2"> 
</div> 
<div class="column1of2"> 
</div> 
<div class="column2of2"> 
</div> 

現在,我看到@ michael.hor257k的答案,我將簡化這個代碼用他的方法。

+0

如果您的問題得到解答,請通過接受答案關閉它。 –

相關問題