我有一个位于http://pastie.org/9604783
的xml文件我在Saxon-HE中使用以下xsl,虽然它不会产生错误(因此它应该是正确的语法)xsl:when语句似乎都没有评估为true,因为所有输出标记都被包装根据{{1}}声明在<bodytext></bodytext>
中。
这些xsl:otherwise
陈述的预期效果是以下
如果xsl:when
元素有
一个a:t
祖先
AND有一个<p.sld>
祖先,它有一个紧接在前的兄弟元素,它具有<r>
的属性:值对
然后输出lvl='1'
中包含的a:t
的内容
OTHERWISE输出包含在<bulleted></bulleted>
a:t
的内容
输出应包含在哪个标记中的变体取决于祖先是<bodytext></bodytext>
还是<p.sld>
以及<p.notes>
属性是否具有值1,2或3
这是我的XSL
lvl
这是所需的XML输出:
<?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>
答案 0 :(得分:3)
尝试和修复这两个主要问题会导致XSLT按预期工作:
ancestor::r
上缺少名称空间前缀。它应该是ancestor::a:r
。preceding-sibling::node
代替preceding-sibling::node()
。前者只会选择名为“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>
答案 1 :(得分:0)
至少,ancestor::r
看起来不对劲。至少OSX有一个perl实用程序xpath
,你可以测试select statemtents。我必须将::r
替换为::a:r
,因为源XML中没有r
节点:
~ 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>
没有做更多的工作,我猜是:
preceding...
中的ancestor::r/preceding-sibling::node[1][@lvl='1']
实际上应该是a:r
的谓词,而不是a:r
的路径
count()
函数是不必要的,正如我的XPath示例所证明的......最基本的XSL测试之一是“节点是否存在”(某些节点数> 0),所以{ {1}}隐含test="a"
而不是所有......
parens,看起来也搞砸了(例如,test="count(a) > 0"
,为什么最后一个paren的)) > 0"
在之外?);只需取消> 0
,直到您真正关心元素的确切数量