给出像这样的源文档:
<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。提示?
答案 0 :(得分:3)
最简单的方法:
<xsl:template match="/A">
<A>
<B>
<xsl:copy-of select=".//C" />
</B>
</A>
</xsl:template>
回答这个问题,为什么你会看到你用XSLT看到的输出:
我猜你有一个
<xsl:apply-templates select="B" />
到位。这意味着:
<xsl:template match="B">
被调用三次,每次<B>
一次。 <B>
,它会执行您想要的操作,有时会将其分支到<xsl:otherwise>
,通过您可能拥有的<C>
复制<xsl:template match="C">
。这是您的额外<C>
来自的地方。...这样的:
<xsl:apply-templates select="B[1]" />
答案 1 :(得分: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。
答案 2 :(得分:1)
要回答你的第二个问题,我使用VS 2008 debugger,它就像一个魅力。
答案 3 :(得分: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>
更新:
如果您希望结果打印得漂亮,并且输入文档中只有空格的文本节点无关紧要,那么您可以将其添加到样式表的顶部(作为<xsl:stylesheet>
的子项):
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>