使用XSL分离输出

时间:2017-02-03 09:05:19

标签: xml xslt

对于误导性的标题感到抱歉,但我不知道更好的表达方式。我正在尝试创建一个XSL,它在我的输出XML中为完全不同类型的数据提供了2个不同的主要部分。但是,我总是在EACH模板调用中获得两种类型的数据。我希望你能给我一个如何实现这个目标的提示。这些是我的成分:

源XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <books>
        <book>Xpages</book>
        <book>XML</book>
    </books>

    <dvds>
        <dvd>Star Wars</dvd>
        <dvd>Prometheus</dvd>
    </dvds>
</root>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <media>
            <xsl:element name="booklist">
                <xsl:call-template name="books"/>
            </xsl:element>
            <xsl:element name="dvdlist">
                <xsl:call-template name="dvds"/>
            </xsl:element>
        </media>
    </xsl:template>

    <xsl:template name="books" match="books">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template name="dvds" match="dvds">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="books/book" name="book">
        <xsl:value-of select="text()"/>
    </xsl:template>

    <xsl:template match="dvds/dvd" name="dvd">
        <xsl:value-of select="text()"/>
    </xsl:template>
</xsl:stylesheet>

这就是我得到的

<?xml version="1.0" encoding="UTF-8"?>
<media>
    <booklist>
        Xpages
        XML    
        Star Wars
        Prometheus    
    </booklist>
    <dvdlist>
        Xpages
        XML    
        Star Wars
        Prometheus
    </dvdlist>
</media>

但这就是我想要的

<?xml version="1.0" encoding="UTF-8"?>
<media>
    <booklist>
        Xpages
        XML
    </booklist>
    <dvdlist>
        Star Wars
        Prometheus
    </dvdlist>
</media>

正如你所看到的,它将我的2个列表加倍。我猜是因为我在两个模板中使用了apply-templates,但必须有办法解决这个问题。非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

您可以从xsl:call-template开始,但在<xsl:apply-templates />内,root将选择所有节点。此时,您仍然位于文档节点上。实际发生的是XSLT的内置模板应用,它首先选择books节点,然后,因为你没有这个模板,它将选择dvds<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <media> <xsl:element name="booklist"> <xsl:apply-templates select="root/books" /> </xsl:element> <xsl:element name="dvdlist"> <xsl:apply-templates select="root/dvds" /> </xsl:element> </media> </xsl:template> <xsl:template match="books/book" name="book"> <xsl:value-of select="text()"/> </xsl:template> <xsl:template match="dvds/dvd" name="dvd"> <xsl:value-of select="text()"/> </xsl:template> </xsl:stylesheet> 节点

您需要做的只是定位您感兴趣的节点。

试试这个XSLT

<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function()  {(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=gm.parentNode.insertBefore(a,m)})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->

答案 1 :(得分:1)

一个解决方案就是这个XSL模板:

<?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" />

    <xsl:template match="/root">
        <media>
            <xsl:element name="booklist">
                <xsl:apply-templates select="books/book" />
            </xsl:element>
            <xsl:element name="dvdlist">
                <xsl:apply-templates select="dvds/dvd" />
            </xsl:element>
        </media>
    </xsl:template>

    <xsl:template match="book">
        <xsl:text>&#xa;</xsl:text><xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="dvd">
        <xsl:text>&#xa;</xsl:text><xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

它的输出是

<?xml version="1.0"?>
<media><booklist>
        Xpages
        XML
    </booklist>
    <dvdlist>
        Star Wars
        Prometheus
    </dvdlist>
</media>