2009-06-03 93 views
0

给定一个源文档,像这样:将一系列元素转换为单个列表的XSLT?

<A> 
    <B> 
    <C>item1</C> 
    </B> 
    <B> 
    <C>item2</C> 
    </B> 
    <B> 
    <C>item3</C> 
    </B> 
</A> 

,我可以使用的产品是这样的什么XSLT:

<A> 
    <B> 
    <C>item1</C> 
    <C>item2</C> 
    <C>item3</C> 
    </B> 
</A> 

我已经尝试了片材...

<xsl:template match="B"> 
    <xsl:choose> 
     <xsl:when test="count(preceding-sibling::B)=0"> 
     <B> 
      <xsl:apply-templates select="./C"/> 
      <xsl:apply-templates select="following-sibling::B"/> 
     </B> 
     </xsl:when> 

     <xsl:otherwise> 
      <xsl:apply-templates select="./C"/> 
     </xsl:otherwise> 

    </xsl:choose> 
    </xsl:template> 

但我越来越...

<A> 
    <B> 
    <C>item1</C> 
    <C>item2</C> 
    <C>item3</C> 
    </B> 
    <C>item2</C> 
    <C>item3</C> 
</A> 

第二个问题:我很难调试XSLT。提示?

回答

3

最简单的方法:

<xsl:template match="/A"> 
    <A> 
    <B> 
     <xsl:copy-of select=".//C" /> 
    </B> 
    </A> 
</xsl:template> 

要回答为什么你看到你与你的XSLT看到输出的问题:

我aussume你有一个

<xsl:apply-templates select="B" /> 
到位

。这意味着:

  • <xsl:template match="B">被称为三次,每个<B>一次。
  • 对于第一<B>,它你打算怎样,其他时间分支右转入<xsl:otherwise>,通过你可能有<xsl:template match="C">复制<C>秒。这是您的额外<C>来自哪里。
  • 要修复它(不,我赞同你的做法),你应该改变它像...

...这样的:

<xsl:apply-templates select="B[1]" /> 
+0

嘿,我这里有一个额外的模板......在上一篇文章中,你有一个:D – 2009-06-03 11:16:44

2

您可以使用Altova的XMLSPY或Visual Studio的调试。以下xslt会给出所需的o/p。

<?xml version="1.0" encoding="UTF-8"?> 
<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:template match="A"> 
     <A> 
      <B> 
       <xsl:apply-templates/> 
      </B> 
     </A> 
    </xsl:template> 
    <xsl:template match="B"> 
     <xsl:copy-of select="C"/> 
    </xsl:template> 
</xsl:stylesheet> 

如果上述SOLN不适合你(我怀疑你是在处理一个更复杂的XML),你可能想贴在你的XML一些更多的信息。

此外,如果需要,具有B和C的模板可以进一步扩展模板o/p。

1

要回答你的第二个问题,我使用VS 2008 debugger,它的作用就像一个魅力。

1

此样式表合并了兄弟<B>元素,而不管样式表中的位置或其他元素名称是什么。

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <!-- By default, copy all nodes unchanged --> 
    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Only copy the first B element --> 
    <xsl:template match="B[1]"> 
    <xsl:copy> 
     <!-- Merge the attributes and content of all sibling B elements --> 
     <xsl:apply-templates select="../B/@* | 
            ../B/node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Don't copy the rest of the B elements --> 
    <xsl:template match="B"/> 

</xsl:stylesheet> 

UPDATE:

如果你想成为漂亮的打印结果,如果只有空白文本节点的输入文档中是微不足道的,那么你可以添加到您的样式表的顶部(作为<xsl:stylesheet>的子女):

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 
相关问题