2014-09-30 24 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的开始已被插入。

目前虽然我得到空输出。所以任何关于如何我上面描述的建议都会受到欢迎。

相关问题