2014-09-29 131 views
0

我有一个XML文件,该文件是在http://pastie.org/9604783为什么这些xsl:当测试总是被评估为false?

我使用与撒克逊-HE下面的XSL,虽然它不会产生错误(所以它应该是正确的语法)没有任何的xsl:when语句似乎应评估为真,因为所有输出标签都按xsl:otherwise声明打包在<bodytext></bodytext>中。

这些xsl:when语句的预期效果是下列

一些变化IF a:t元件具有 一个<p.sld>祖先 并且具有<r>祖先具有其具有的属性的紧接在前的同级元素:值对lvl='1' THEN输出的该a:t的内容包在<bulleted></bulleted> 以其他方式输出该a:t包裹的内容物在<bodytext></bodytext>

什么标签输出应该被包裹在变化取决于是否祖先是<p.sld><p.notes>lvl属性是否具有值为1,2,或3

这里是我的XSL

<?xml version="1.0" encoding="UTF-8"?> 
<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:choose> 
     <xsl:when test="(count(ancestor::p:sld) > 0) and (count(ancestor::r/preceding-sibling::node[1][@lvl='1'])) > 0"> 
     <bulleted> 
      <xsl:value-of select="."/> 
     </bulleted> 
     </xsl:when> 
     <xsl:when test="(count(ancestor::p:sld) > 0) and (count(ancestor::r/preceding-sibling::node[1][@lvl='2'])) > 0"> 
     <bulleted2> 
      <xsl:value-of select="."/> 
     </bulleted2> 
     </xsl:when> 
     <xsl:when test="(count(ancestor::p:notes) > 0) and (count(ancestor::r/preceding-sibling::node[1][@lvl='2'])) > 0"> 
     <bulleted> 
      <xsl:value-of select="."/> 
     </bulleted> 
     </xsl:when> 
     <xsl:when test="(count(ancestor::p:notes) > 0) and (count(ancestor::r/preceding-sibling::node[1][@lvl='3'])) > 0"> 
     <bulleted2> 
      <xsl:value-of select="."/> 
     </bulleted2> 
     </xsl:when> 
     <xsl:otherwise> 
     <bodytext> 
      <xsl:value-of select="."/> 
     </bodytext> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

下面是所需的XML输出:

<?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"> 
    <bodytext>header text</bodytext> 
    <bodytext>body text </bodytext> 
    <bodytext>body text </bodytext> 
    <bodytext>body text </bodytext> 
    <bulleted>bulleted text</bulleted> 
    <bulleted>bulleted text</bulleted> 
    <bulleted>bulleted text</bulleted> 
    <bulleted2>bulleted2 text</bulleted2> 
    <bulleted2>bulleted2 text</bulleted2> 
    <bulleted2>bulleted2 text</bulleted2> 
    <bulleted2>bulleted2 text</bulleted2> 
    <bulleted>bulleted text</bulleted> 
    <bulleted>bulleted text</bulleted> 
    <bulleted>bulleted text</bulleted> 
    <bulleted>bulleted text</bulleted> 
    <bodytext>body text</bodytext> 
    <bodytext>body text</bodytext> 
    <bodytext>footer text</bodytext> 
    <bodytext>10</bodytext> 
    <bodytext>10</bodytext> 
    <bodytext>notes header text</bodytext> 
    <bodytext>notes body text </bodytext> 
    <bodytext>notes body text </bodytext> 
    <bodytext>notes table header text</bodytext> 
    <bodytext>notes table header text</bodytext> 
    <bodytext>notes table body text</bodytext> 
    <bodytext>notes table body text</bodytext> 
    <bodytext>notes table body text</bodytext> 
    <bodytext>notes table body text</bodytext> 
    <bodytext>notes table body text</bodytext> 
    <bodytext>notes table body text</bodytext> 
</document> 
+3

请将您的示例最小化为仅显示问题的必要条件。 – 2014-09-29 17:29:20

+0

这将有所帮助。 – 2014-09-29 17:36:44

回答

3

没有与您尝试两个主要的问题和解决这些应该引起预期的XSLT工作:

  • 你是缺少名称空间前缀ancestor::r。它应该是ancestor::a:r
  • 您正在使用preceding-sibling::node而不是preceding-sibling::node()。前者只会选择名为“节点”的元素,其中没有。
    • 但是,实际上应该使用preceding-sibling::*而不是这两者之一,以免空白文本节点受阻。

所有这一切说,你的方法可以通过使用变量和摆脱不必要的count(...) > 0东西被清理了很多。以下应该会产生预期的输出:

<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="sld" select="ancestor::p:sld" /> 
    <xsl:variable name="notes" select="ancestor::p:notes" /> 
    <xsl:variable name="levelBeforeR" 
        select="ancestor::a:r/preceding-sibling::*[1]/@lvl" /> 

    <xsl:variable name="wrapperName"> 
     <xsl:choose> 
     <xsl:when test="$sld and $levelBeforeR = '1' or 
         $notes and $levelBeforeR = '2'"> 
      <xsl:text>bulleted</xsl:text> 
     </xsl:when> 
     <xsl:when test="$sld and $levelBeforeR = '2' or 
         $notes and $levelBeforeR = '3'"> 
      <xsl:text>bulleted2</xsl:text> 
     </xsl:when> 
     <xsl:otherwise>bodytext</xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 

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

</xsl:stylesheet> 
+0

谢谢!作为后续是否有一种简单的方法来扩展它,以包装每个p:sld的第一个“a:t”后代的内容,其标记为“”,每个p的第一个“a:t”后裔:笔记'与标记''?这不是通常应用的另一个包装标签(不包括)。 – 2014-09-30 19:03:11

+0

决定发布,作为一个全新的问题。见[link](http://stackoverflow.com/questions/26130774/selecting-first-descendant-of-a-certain-name-for-each-instance-of-a-particular-a) – 2014-09-30 21:57:56

0

最起码,ancestor::r看起来是错误的。至少OSX有一个perl实用程序,xpath,您可以测试select statemtents。我不得不更换::r::a:r因为没有r节点源XML:

~ zyoung$ xpath so.xml "//a:t[ancestor::p:sld and ancestor::r]" 
No nodes found 
~ zyoung$ xpath so.xml "//a:t[ancestor::p:sld and ancestor::a:r]" 
Found 18 nodes: 
-- NODE -- 
<a:t>header text</a:t>-- NODE -- 
<a:t>body text </a:t>-- NODE -- 
<a:t>body text </a:t>-- NODE -- 
<a:t>body text </a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>bulleted2 text</a:t>-- NODE -- 
<a:t>bulleted2 text</a:t>-- NODE -- 
<a:t>bulleted2 text</a:t>-- NODE -- 
<a:t>bulleted2 text</a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>bulleted text</a:t>-- NODE -- 
<a:t>body text</a:t>-- NODE -- 
<a:t>body text</a:t>-- NODE -- 
<a:t>footer text</a:t> 

没有做任何更多的工作,我猜:

  1. preceding...ancestor::r/preceding-sibling::node[1][@lvl='1']实际上应该是谓词a:r,而不是路径a:r

  2. count()函数NS是不必要的,因为我的XPath实例证明......最基本的XSL测试是“没有一个节点存在”的一个(一些节点数量> 0),所以test="a"意味着test="count(a) > 0"没有所有...

  3. 的parens,这也看起来搞砸了(例如,)) > 0",为什么> 0以外的最后paren?);只是count()做掉,直到你真正关心的元素的确切数目

相关问题