2014-09-30 48 views
0

我有一些複雜的MS-Office XML,看起來像您在鏈接中看到的內容,但是完整的源代碼更長,文檔根的許多p:sldp:notes子級。總是出現在順序p:sldp:notesp:sldp:noteshttp://pastie.org/9604783爲特定祖先的每個實例選擇某個特定名稱的第一個後代

感謝JLRishe,我有一些XSL提取後代a:t元素和基於上下文的各種標籤的包裝及其內容。

這XSL是如下

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"> 
    <xsl:output method="xml"/> 

    <xsl:template match="/"> 
    <document> 
     <xsl:apply-templates select="//a:t"/> 
    </document> 
    </xsl:template> 

    <xsl:template match="a:t"> 
    <xsl:variable name="sldAncestor" select="ancestor::p:sld" /> 
    <xsl:variable name="notesAncestor" select="ancestor::p:notes" /> 
    <xsl:variable name="rAncestorPreLevel" 
        select="ancestor::a:r/preceding-sibling::*[1]/@lvl" /> 

    <xsl:variable name="wrapperName"> 
     <xsl:choose> 

     <xsl:when test="$sldAncestor and $rAncestorPreLevel = '1'"> 
      <xsl:text>SlideBullet</xsl:text> 
     </xsl:when> 
     <xsl:when test="$sldAncestor and $rAncestorPreLevel = '2'"> 
      <xsl:text>SlideBullet1</xsl:text> 
     </xsl:when> 
     <xsl:when test="$sldAncestor and $rAncestorPreLevel = '3'"> 
      <xsl:text>SlideBullet2</xsl:text> 
     </xsl:when> 

     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '0'" > 
      <xsl:text>StudentNotes</xsl:text> 
     </xsl:when> 

     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '1'" > 
      <xsl:text>StudentNotes</xsl:text> 
     </xsl:when> 

     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '2'"> 
      <xsl:text>Student_Notes_Bullet</xsl:text> 
     </xsl:when> 
     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '3'"> 
      <xsl:text>Student_Notes_Bullet_1</xsl:text> 
     </xsl:when> 

     <xsl:otherwise>Body</xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 

    <xsl:element name="{$wrapperName}"> 
     <xsl:value-of select="." /> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

但我想展開能夠選擇每個p:sld內出現的第一個a:t元素和包裝,在標籤<SlideTitleGhost></SlideTitleGhost>

同樣地,我希望能夠選擇每個p.notes元素 中的第一個a:t元素,並與標籤<PageBreak /><StudentNotes></StudentNotes>

請注意,並非所有的a:t元素是同級的包裹的內容。同胞a:t元素是a:r元素的子元素,但是有多個a:r元素來自各個p:notesp:sld元素。那些a:r元素也不能期望是兄弟姐妹。每個a:t元素的xpath的最後一部分變爲//p:cSld/p:spTree/p:sp/p:txBody/a:p/a:r/a:t

我在Windows上使用Saxon-HE,但如果需要可以切換處理器。

期望的輸出將如下所示。

<?xml version="1.0" encoding="UTF-8"?> 
<document xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"> 
    <SlideTitleGhost>header text</SlideTitleGhost> 
    <Body>body text </Body> 
    <Body>body text </Body> 
    <Body>body text </Body> 
    <SlideBullet>bulleted text</SlideBullet> 
    <SlideBullet>bulleted text</SlideBullet> 
    <SlideBullet>bulleted text</SlideBullet> 
    <SlideBullet1>bulleted2 text</SlideBullet1> 
    <SlideBullet1>bulleted2 text</SlideBullet1> 
    <SlideBullet1>bulleted2 text</SlideBullet1> 
    <SlideBullet1>bulleted2 text</SlideBullet1> 
    <SlideBullet>bulleted text</SlideBullet> 
    <SlideBullet>bulleted text</SlideBullet> 
    <SlideBullet>bulleted text</SlideBullet> 
    <SlideBullet>bulleted text</SlideBullet> 
    <Body>body text</Body> 
    <Body>body text</Body> 
    <Body>footer text</Body> 
    <Body>10</Body> 
    <Body>10</Body> 
    <PageBreak /> 
    <StudentNotes>notes header text</StudentNotes> 
    <Body>notes body text</Body> 
    <StudentNotes>notes body text</StudentNotes> 
    <StudentNotes>notes table header text</StudentNotes> 
    <StudentNotes>notes table header text</StudentNotes> 
    <StudentNotes>notes table body text</StudentNotes> 
    <StudentNotes>table body text</StudentNotes> 
    <StudentNotes>notes table body text</StudentNotes> 
    <StudentNotes>notes table body text</StudentNotes> 
    <StudentNotes>notes table body text</StudentNotes> 
    <StudentNotes>notes table body text</StudentNotes> 
</document> 
+0

爲每個案例設置模板,調整模板優先級,以便在默認情況下異常匹配。 – keshlam 2014-10-01 04:08:09

回答

0

我能夠得到足夠接近期望的結果(和擺脫最後一個的:每個p下的T形元件:SLD)具有以下XSL

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"> 
    <xsl:output method="xml"/> 

    <xsl:template match="/"> 
    <document> 
     <xsl:apply-templates select="//a:t"/> 
    </document> 
    </xsl:template> 

    <xsl:template match="a:t"> 
    <xsl:variable name="sldAncestor" select="ancestor::p:sld" /> 
    <xsl:variable name="notesAncestor" select="ancestor::p:notes" /> 
    <xsl:variable name="rAncestorPreLevel" select="ancestor::a:r/preceding-sibling::a:pPr/@lvl" /> 
    <xsl:variable name="SlideTitle" select="ancestor::p:txBody/preceding-sibling::p:nvSpPr/p:nvPr/p:ph/@type" /> 

    <xsl:variable name="wrapperName"> 

    <xsl:choose> 
     <xsl:when test="$sldAncestor and $rAncestorPreLevel = '1'"> 
      <xsl:text>SlideBullet</xsl:text> 
     </xsl:when> 
     <xsl:when test="$sldAncestor and $rAncestorPreLevel = '2'"> 
      <xsl:text>SlideBullet1</xsl:text> 
     </xsl:when> 
     <xsl:when test="$sldAncestor and $rAncestorPreLevel = '3'"> 
      <xsl:text>SlideBullet2</xsl:text> 
     </xsl:when> 
     <xsl:when test="$sldAncestor and $SlideTitle = 'title'"> 
      <xsl:text>SlideTitleGhost</xsl:text> 
     </xsl:when> 

     <xsl:when test="$notesAncestor and not(ancestor::a:r/preceding-sibling::a:pPr/@lvl)"> 
      <xsl:text>StudentNotes</xsl:text> 
     </xsl:when> 

     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '1'" > 
      <xsl:text>StudentNotes</xsl:text> 
     </xsl:when> 

     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '2'"> 
      <xsl:text>Student_Notes_Bullet</xsl:text> 
     </xsl:when> 
     <xsl:when test="$notesAncestor and $rAncestorPreLevel = '3'"> 
      <xsl:text>Student_Notes_Bullet_1</xsl:text> 
     </xsl:when> 

     <xsl:otherwise>SlideTopic</xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 

    <xsl:choose> 
     <xsl:when test="not($notesAncestor and ancestor::a:fld)"> 
      <xsl:element name="{$wrapperName}"> 
         <xsl:value-of select="." /> 
      </xsl:element> 
     </xsl:when> 
     <xsl:when test="$notesAncestor and ancestor::a:fld"> 
     <xsl:element name="PageBreak"></xsl:element> 
      </xsl:when> 
</xsl:choose> 

    </xsl:template> 

</xsl:stylesheet> 

我做到了通過識別p:sld元素(ancestor::p:txBody/preceding-sibling::p:nvSpPr/p:nvPr/p:ph/@type)的每個第一個a:t後代元素的唯一條件。第二個添加到底部的xsl:choose讓我拋出最後的a:t在每個p:sld,我不希望包括在輸出中,因爲它不需要輸出,並使用它作爲插入<pagebreak>標籤的時刻我確實希望在p:notes的第一個a:t後裔之前。

更新:事實證明,這不是一個解決方案,因爲文檔順序與許多頁面上源PowerPoint文檔從上到下在頁面上出現的順序不匹配。在許多情況下,出現在每張幻燈片頂部的標題文本在doc順序中顯示爲a:t元素後面的其他a:t元素。

我正在研究一個解決方案,根據根的孩子是p:sld還是p:notes來應用兩個不同的模板。當上下文是根元素時,將模板應用於"p:sld|p:notes"

如果slects p:sld的XSLT查找後代a的值:&將得到裹在<SlideTitleGhost>,存儲在一個變量的值,然後輸出<SlideTitleGhost> $變量</SlideTitleGhost>隨後施加模板後代a:t元素除了將會丟棄在<SlideTitleGhost>中包含其內容的a:t元素之外。

如果它選擇p:notes它只是將a:t應用於模板。 <PageBreak></PageBreak>當最後一個a:t元素被刪除時,標記p:notes的開始已被插入。

目前雖然我得到空輸出。所以任何關於如何我上面描述的建議都會受到歡迎。

相關問題