繁体   English   中英

XSLT-2.0 IF语句/分组

[英]XSLT-2.0 IF statement/grouping

我是XSLT和XML的新手,并试图使用XSLT从XML文件创建CSV。 我有大量的学院数据,涉及某些年份,他们发表了不同类型的内容,例如书籍,书籍中的章节,期刊文章等,我希望将它们制成表格,以显示每年每种出版物的数量。所以:

Year, 1990, 1993, 1995, 1994, .....2017, 2018
Book,  1,3,0,0,...1,1
Journal Article,  2,1,0,1,...1,1
Book Chapter, 1, 1,0,0,...0,0

如您所见,对于他们没有任何特定类型的出版物的年份,我想将其强制为零。 我能够将其绘制成不带零的形式绘制它们,但是出于数据目的,我想强制使用它。 这是我们的XML文档的格式:

<?xml version="1.0" encoding="UTF-8"?>    
<Data xmlns="http://www.digitalmeasures.com/schema/data" xmlns:dmd="http://www.digitalmeasures.com/schema/data-metadata" dmd:date="2017-10-16">
    <Record userId="1898739" username="50019019" termId="5923" dmd:surveyId="17683692">
        <dmd:IndexEntry indexKey="COLLEGE" entryKey="College of Engineering" text="College of Engineering"/>
        <dmd:IndexEntry indexKey="DEPARTMENT" entryKey="Civil, Architectural, &amp; Environmental Engineering" text="Civil, Architectural, &amp; Environmental Engineering"/>
        <INTELLCONT id="151368386560" dmd:originalSource="MANAGE_DATA" dmd:lastModified="2017-10-03T10:47:54" dmd:startDate="2016-01-01" dmd:endDate="2016-12-31">
            <REFEREED>Yes</REFEREED>
            <CONTYPE>Journal Article</CONTYPE>
            <CONTYPEOTHER/>
            <STATUS>Published</STATUS>
            <TITLE>Sample data</TITLE>
            <TITLE_SECONDARY/>
            <INTELLCONT_AUTH id="151368386563">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="151368386561">
                <FACULTY_NAME>1898739</FACULTY_NAME>
                <FNAME>sample</FNAME>
                <MNAME>sample</MNAME>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <PUBLISHER>sample</PUBLISHER>
            <PUBCTYST/>
            <PUBCNTRY/>
            <VOLUME>13</VOLUME>
            <ISSUE>11</ISSUE>
            <PAGENUM>117</PAGENUM>
            <WEB_ADDRESS/>
            <DOI>sample</DOI>
            <ISBNISSN/>
            <PMCID/>
            <AUDIENCE/>
            <PUBLICAVAIL/>
            <ABSTRACT/>
            <FULL_TEXT/>
            <DTM_EXPSUB/>
            <DTD_EXPSUB/>
            <DTY_EXPSUB/>
            <EXPSUB_START></EXPSUB_START>
            <EXPSUB_END></EXPSUB_END>
            <DTM_SUB/>
            <DTD_SUB/>
            <DTY_SUB/>
            <SUB_START></SUB_START>
            <SUB_END></SUB_END>
            <DTM_ACC/>
            <DTD_ACC/>
            <DTY_ACC/>
            <ACC_START></ACC_START>
            <ACC_END></ACC_END>
            <DTM_PUB/>
            <DTD_PUB/>
            <DTY_PUB>2016</DTY_PUB>
            <PUB_START>2016-01-01</PUB_START>
            <PUB_END>2016-12-31</PUB_END>
            <USER_REFERENCE_CREATOR>Yes</USER_REFERENCE_CREATOR>
        </INTELLCONT>
        <INTELLCONT  dmd:originalSource="IMPORT" dmd:lastModified="2017-10-03T11:17:33" dmd:startDate="2016-01-01" dmd:endDate="2016-12-31">
            <REFEREED>Yes</REFEREED>
            <CONTYPE>Journal Article</CONTYPE>
            <CONTYPEOTHER/>
            <STATUS>Published</STATUS>
            <TITLE>Sample</TITLE>
            <TITLE_SECONDARY/>
            <INTELLCONT_AUTH id="141176756225">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756226">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756227">
                <FACULTY_NAME>1898739</FACULTY_NAME>
                <FNAME>sample</FNAME>
                <MNAME>sample</MNAME>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756228">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME>sample</MNAME>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756229">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756230">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>sample</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756231">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756232">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756233">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME>sample</MNAME>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756234">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <INTELLCONT_AUTH id="141176756235">
                <FACULTY_NAME/>
                <FNAME>sample</FNAME>
                <MNAME/>
                <LNAME>sample</LNAME>
                <INSTITUTION/>
                <ROLE>Author</ROLE>
                <STUDENT_LEVEL/>
            </INTELLCONT_AUTH>
            <PUBLISHER>sample</PUBLISHER>
            <PUBCTYST/>
            <PUBCNTRY/>
            <VOLUME>23</VOLUME>
            <ISSUE/>
            <PAGENUM>2003-2013</PAGENUM>
            <WEB_ADDRESS/>
            <DOI>sample</DOI>
            <ISBNISSN/>
            <PMCID/>
            <AUDIENCE/>
            <PUBLICAVAIL/>
            <ABSTRACT/>
            <FULL_TEXT/>
            <DTM_EXPSUB/>
            <DTD_EXPSUB/>
            <DTY_EXPSUB/>
            <EXPSUB_START></EXPSUB_START>
            <EXPSUB_END></EXPSUB_END>
            <DTM_SUB/>
            <DTD_SUB/>
            <DTY_SUB/>
            <SUB_START></SUB_START>
            <SUB_END></SUB_END>
            <DTM_ACC/>
            <DTD_ACC/>
            <DTY_ACC/>
            <ACC_START></ACC_START>
            <ACC_END></ACC_END>
            <DTM_PUB/>
            <DTD_PUB/>
            <DTY_PUB>2016</DTY_PUB>
            <PUB_START>2016-01-01</PUB_START>
            <PUB_END>2016-12-31</PUB_END>
            <USER_REFERENCE_CREATOR>Yes</USER_REFERENCE_CREATOR>
        </INTELLCONT>
    </Record>            <!-- Added by edit -->
</Data>                  <!-- Added by edit -->

出于明显的原因,所有机密信息已被单词“ sample”代替,但这不应影响逻辑。 因此,我当前的XSLT多年来一直在打印,然后是类似的文章类型:

Type
Journal Article,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,
,1,3,3,1,2,1,2,3,8,2,12,11,5,6,10,11,4,5,4,7,10,4,

Book,1995,2006,2008,2011,
,1,1,1,1,

Book Chapter,2005,2006,2008,2011,2015,2016,
,1,3,3,2,1,1,

Abstract,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,
,8,22,12,6,13,9,6,18,5,3,4,2,7,1,

Other,2004,2005,2006,2007,2008,
,2,3,2,2,8,

Total,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,
,1,1,3,3,1,2,1,2,3,25,38,34,19,31,17,17,32,10,8,8,11,19,6,

这是XSLT-2.0供参考:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:csv="csv:csv"
    xmlns="http://www.w3.org/1999/xhtml" xmlns:dm="http://www.digitalmeasures.com/schema/data"
    xmlns:dmd="http://www.digitalmeasures.com/schema/data-metadata"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="array fn map math xhtml xs">

    <xsl:output method="text" encoding="utf-8"/>
    <xsl:variable name="delimiter" select="','"/>
    <!-- xmlns:dm is the xmlns attribute in Data.-->

    <xsl:template match="/dm:Data">
        <xsl:text>Type</xsl:text>
        <xsl:text>&#xa;</xsl:text>        
        <!--Journal Article Publications-->
        <xsl:text>Journal Article,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Journal Article']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="(current-grouping-key())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Journal Article']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="count(current-group())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>&#xa;</xsl:text>

        <!-- Book Publications -->
        <xsl:text>Book,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Book']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="(current-grouping-key())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Book']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="count(current-group())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>&#xa;</xsl:text>

        <!--Book Chapter Publications-->
        <xsl:text>Book Chapter,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Book Chapter']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="(current-grouping-key())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Book Chapter']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="count(current-group())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>&#xa;</xsl:text>

        <!--Abstract Publications-->
        <xsl:text>Abstract,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Abstract']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="(current-grouping-key())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Abstract']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="count(current-group())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>&#xa;</xsl:text>

        <!--Other Publications-->
        <xsl:text>Other,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Other']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="(current-grouping-key())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT[dm:CONTYPE='Other']" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="count(current-group())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>&#xa;</xsl:text>

        <xsl:text>Total,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="(current-grouping-key())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>

        <xsl:text>,</xsl:text>
        <xsl:for-each-group select="dm:Record/dm:INTELLCONT" group-by="dm:DTY_PUB">
            <xsl:sort select="current-grouping-key()" />
            <xsl:value-of select="count(current-group())" />
            <xsl:text>,</xsl:text>
        </xsl:for-each-group>
        <xsl:text>&#xa;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

因此,我认为我需要在代码中包含某种If语句,以便仅打印所有年份,然后在某些类型的出版物不存在的年份中强制为零。

这是某种逻辑上听起来像我的伪代码:

<xsl:for-each-group select="dm:Record/dm:INTELLCONT" group-by="dm:DTY_PUB">
  <xsl:sort select="current-grouping-key()" /> 
  <xsl:if test = "dm:Record/dm:INTELLCONT/dm:CONTYPE != 'Book'">  //if the type of content is not of Book, print zero for that year
                    print ("0,")    
             else: <xsl:value-of select="count(current-group())" /> <xsl:text>,</xsl:text> // otherwise, print the number of Books published that year.     
  </xsl:if> 
</xsl:for-each-group>

如果我的问题不清楚,请告诉我。
我花了大量时间试图使它尽可能清晰。

我想我们不需要样本中的所有这些元素,听起来您有一个子元素可以提供类型或类别的分组依据,并且您有一年的时间。 所以我创建了一些更简单的样本数据

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <items>
        <item>
            <category>a</category>
            <year>2000</year>
        </item>
        <item>
            <category>a</category>
            <year>2017</year>
        </item>
        <item>
            <category>a</category>
            <year>2000</year>
        </item>
        <item>
            <category>b</category>
            <year>1999</year>
        </item>
        <item>
            <category>b</category>
            <year>2018</year>
        </item>
        <item>
            <category>b</category>
            <year>1999</year>
        </item> 
        <item>
            <category>b</category>
            <year>2000</year>
        </item> 
    </items>
</root>

和XSLT 3样式表(可以与Saxon 9.8所有版本一起使用),使用组合键可以按类别和年份标识一组项目。 使用minmax函数可以简单地创建年份列表。 所以用

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:output method="text"/>

    <xsl:key name="cat-year" match="items/item" composite="yes" use="category, xs:integer(year)"/>

    <xsl:variable name="input-doc" select="."/>

    <xsl:template match="/">
        <xsl:variable name="min-year" as="xs:integer" select="min(root/items/item/year/xs:integer(.))"/>
        <xsl:variable name="max-year" as="xs:integer" select="max(root/items/item/year/xs:integer(.))"/>
        <xsl:variable name="categories" select="distinct-values(root/items/item/category)"/>
        <xsl:variable name="years" as="xs:integer*" select="$min-year to $max-year"/>
        <xsl:value-of select="$years" separator=","/>
        <xsl:text>&#10;</xsl:text>
        <xsl:for-each select="$categories">
            <xsl:variable name="cat" select="."/>
            <xsl:value-of select="."/>
            <xsl:text>&#10;</xsl:text>
            <xsl:value-of select="$years!count(key('cat-year', ($cat, .), $input-doc))" separator=","/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

我懂了

1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018
a
0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
b
2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1

尝试使其适应您的XML格式。 让我们知道您是可以使用XSLT 3还是被XSLT 2所困扰,在这种情况下,您可以定义一个将类别和年份连接在一起的键,其余代码应相同:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output method="text"/>

    <xsl:key name="cat-year" match="items/item" use="concat(category, '|', year)"/>

    <xsl:variable name="input-doc" select="."/>

    <xsl:template match="/">
        <xsl:variable name="min-year" as="xs:integer" select="min(root/items/item/year/xs:integer(.))"/>
        <xsl:variable name="max-year" as="xs:integer" select="max(root/items/item/year/xs:integer(.))"/>
        <xsl:variable name="categories" select="distinct-values(root/items/item/category)"/>
        <xsl:variable name="years" as="xs:integer*" select="$min-year to $max-year"/>
        <xsl:value-of select="$years" separator=","/>
        <xsl:text>&#10;</xsl:text>
        <xsl:for-each select="$categories">
            <xsl:variable name="cat" select="."/>
            <xsl:value-of select="."/>
            <xsl:text>&#10;</xsl:text>
            <xsl:value-of select="for $y in $years return count(key('cat-year', concat($cat, '|', $y), $input-doc))" separator=","/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

@Martin Honnen发布了一个效果很好的解决方案,我将其应用到了我自己的问题中,下面是代码,以防有人希望看到它如何特别适用于我的情况:

<xsl:key name="Contype-Year" match="dm:Data/dm:Record/dm:INTELLCONT" use="concat(dm:CONTYPE, '|', dm:DTY_PUB)"/>

    <xsl:variable name="input-doc" select="."/>

    <xsl:template match="/">
        <xsl:variable name="min-year" as="xs:integer" select="min(dm:Data/dm:Record/dm:INTELLCONT/dm:DTY_PUB/xs:integer(.))"/>
        <xsl:variable name="max-year" as="xs:integer" select="max(dm:Data/dm:Record/dm:INTELLCONT/dm:DTY_PUB/xs:integer(.))"/>
        <xsl:variable name="categories" select="distinct-values(dm:Data/dm:Record/dm:INTELLCONT/dm:CONTYPE)"/>
        <xsl:variable name="years" as="xs:integer*" select="$min-year to $max-year"/>
        <xsl:value-of select="$years" separator=","/>
        <xsl:text>&#10;</xsl:text>
        <xsl:for-each select="$categories">
            <xsl:variable name="cat" select="."/>
            <xsl:value-of select="."/>
            <xsl:text>&#10;</xsl:text>
            <xsl:value-of select="for $y in $years return count(key('Contype-Year', concat($cat, '|', $y), $input-doc))" separator=","/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM