XSLT将此xml获取为表格格式

时间:2016-04-20 02:24:26

标签: xml xslt xslt-3.0

以下是我有一个xml文件的小样本

<?xml version="1.0" encoding="utf-8"?>
        <!DOCTYPE population SYSTEM "http://www.matsim.org/files/dtd/population_v5.dtd">

        <population>

        <!-- ====================================================================== -->

            <person id="10000061">
                <plan score="219.62581874242716" selected="yes">
                    <act type="home" link="21258" x="334867.243653" y="3126570.70778" start_time="03:00:00" end_time="15:07:00" />
                    <leg mode="ride" dep_time="15:07:00" trav_time="00:03:27" arr_time="15:10:27">
                        <route type="links">21258 14045 13977 13939 13925 13919 13905 13904</route>
                    </leg>
                    <act type="shop" link="13904" x="332634.86999" y="3127078.96383" start_time="15:12:00" end_time="16:21:00" />
                    <leg mode="car" dep_time="16:21:00" trav_time="00:09:44" arr_time="16:30:44">
                        <route type="links">13904 21207 21208 13980 21187 21188 14148 14144 14130 14129</route>
                    </leg>
                    <act type="shop" link="14129" x="331666.364904" y="3129306.48785" start_time="16:25:00" end_time="17:37:00" />
                    <leg mode="ride" dep_time="17:37:00" trav_time="00:09:46" arr_time="17:46:46">
                        <route type="links">14129 14143 14147 14161 14171 14189 14195 14120 14106 14051 13941 13938 13976 14044 21259 21258</route>
                    </leg>
                    <act type="home" link="21258" x="334867.243653" y="3126570.70778" start_time="17:45:00" end_time="26:59:00" />
                </plan>

                <plan score="218.9756035020247" selected="no">
                    <act type="home" link="21258" x="334867.243653" y="3126570.70778" start_time="03:00:00" end_time="15:07:00" />
                    <leg mode="ride" dep_time="15:07:00" trav_time="00:03:26" arr_time="15:10:26">
                        <route type="links">21258 14045 13977 13939 13925 13919 13905 13904</route>
                    </leg>
                    <act type="shop" link="13904" x="332634.86999" y="3127078.96383" start_time="15:12:00" end_time="16:21:00" />
                    <leg mode="car" dep_time="16:21:00" trav_time="00:08:46" arr_time="16:29:46">
                        <route type="links">13904 13905 13891 13855 21239 21240 13887 13885 13869 13870 13920 13974 14070 14075 14103 14109 14123 14129</route>
                    </leg>
                    <act type="shop" link="14129" x="331666.364904" y="3129306.48785" start_time="16:25:00" end_time="17:37:00" />
                    <leg mode="ride" dep_time="17:37:00" trav_time="00:11:06" arr_time="17:48:06">
                        <route type="links">14129 14143 14147 14161 14150 14098 14094 14095 14113 14106 14051 13941 13938 13976 14044 21259 21258</route>
                    </leg>
                    <act type="home" link="21258" x="334867.243653" y="3126570.70778" start_time="17:45:00" end_time="26:59:00" />
                </plan>

                <plan score="218.5148700010285" selected="no">
                    <act type="home" link="21258" x="334867.243653" y="3126570.70778" start_time="03:00:00" end_time="15:07:00" />
                    <leg mode="ride" dep_time="15:07:00" trav_time="00:03:26" arr_time="15:10:26">
                        <route type="links">21258 14045 13977 13939 13925 13919 13905 13904</route>
                    </leg>
                    <act type="shop" link="13904" x="332634.86999" y="3127078.96383" start_time="15:12:00" end_time="16:21:00" />
                    <leg mode="car" dep_time="16:21:00" trav_time="00:08:15" arr_time="16:29:15">
                        <route type="links">13904 13905 13906 13980 21187 21188 14148 14144 14130 14129</route>
                    </leg>
                    <act type="shop" link="14129" x="331666.364904" y="3129306.48785" start_time="16:25:00" end_time="17:37:00" />
                    <leg mode="ride" dep_time="17:37:00" trav_time="00:11:18" arr_time="17:48:18">
                        <route type="links">14129 14130 14124 14110 14104 14077 14071 13975 13921 13871 13868 13884 13886 13888 13894 13904 13918 13924 13938 13976 14044 21259 21258</route>
                    </leg>
                    <act type="home" link="21258" x="334867.243653" y="3126570.70778" start_time="17:45:00" end_time="26:59:00" />
                </plan>

            </person>

        <!-- ====================================================================== -->

            <person id="10000302">
                <plan score="209.66504470021556" selected="yes">
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="03:00:00" end_time="07:56:00" />
                    <leg mode="car" dep_time="07:56:00" trav_time="00:03:00" arr_time="07:59:00">
                        <route type="links">21256 13966 14056 14057</route>
                    </leg>
                    <act type="work" link="14057" x="335957.065395" y="3128105.16619" start_time="08:04:00" end_time="10:28:00" />
                    <leg mode="car" dep_time="10:28:00" trav_time="00:08:20" arr_time="10:36:20">
                        <route type="links">14057 14049 14045 13977 13939 13925 13919 21207 21208 13980 14046 14095 21191</route>
                    </leg>
                    <act type="social" link="21191" x="333032.807855" y="3128759.66141" start_time="10:33:00" end_time="11:52:00" />
                    <leg mode="car" dep_time="11:52:00" trav_time="00:08:33" arr_time="12:00:33">
                        <route type="links">21191 21194 14189 14195 14197 14210 14212 14234 14246 14215 14192 14178 14057 13967 21257 21256</route>
                    </leg>
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="11:59:00" end_time="12:11:00" />
                    <leg mode="car" dep_time="12:11:00" trav_time="00:06:35" arr_time="12:17:35">
                        <route type="links">21256 21257 21258 14045 13977 13939 13925 13919 13905 13906</route>
                    </leg>
                    <act type="social" link="13906" x="332302.159169" y="3127536.46778" start_time="12:17:00" end_time="13:30:00" />
                    <leg mode="car" dep_time="13:30:00" trav_time="00:05:30" arr_time="13:35:30">
                        <route type="links">13906 13907 13904 13918 13924 13938 13976 14044 21259 21256</route>
                    </leg>
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="13:36:00" end_time="26:59:00" />
                </plan>

                <plan score="205.5456839457717" selected="no">
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="03:00:00" end_time="07:56:00" />
                    <leg mode="car" dep_time="07:56:00" trav_time="00:02:15" arr_time="07:58:15">
                        <route type="links">21256 13966 14056 14057</route>
                    </leg>
                    <act type="work" link="14057" x="335957.065395" y="3128105.16619" start_time="08:04:00" end_time="10:28:00" />
                    <leg mode="car" dep_time="10:28:00" trav_time="00:06:51" arr_time="10:34:51">
                        <route type="links">14057 14056 14177 14191 14214 14247 14235 14213 14211 14198 14120 14114 21191</route>
                    </leg>
                    <act type="social" link="21191" x="333032.807855" y="3128759.66141" start_time="10:33:00" end_time="11:52:00" />
                    <leg mode="car" dep_time="11:52:00" trav_time="00:07:45" arr_time="11:59:45">
                        <route type="links">21191 21194 14189 14195 14197 14210 14212 14234 14246 14215 14192 14178 14057 13967 21257 21256</route>
                    </leg>
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="11:59:00" end_time="12:11:00" />
                    <leg mode="car" dep_time="12:11:00" trav_time="00:07:51" arr_time="12:18:51">
                        <route type="links">21256 13915 13823 13767 13743 13731 13732 13837 13831 13819 13820 13854 13890 13906</route>
                    </leg>
                    <act type="social" link="13906" x="332302.159169" y="3127536.46778" start_time="12:17:00" end_time="13:30:00" />
                    <leg mode="car" dep_time="13:30:00" trav_time="00:08:54" arr_time="13:38:54">
                        <route type="links">13906 13907 13904 13918 13924 13938 13976 14044 21259 21256</route>
                    </leg>
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="13:36:00" end_time="26:59:00" />
                </plan>

                <plan score="203.4205865037132" selected="no">
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="03:00:00" end_time="07:56:00" />
                    <leg mode="car" dep_time="07:56:00" trav_time="00:03:15" arr_time="07:59:15">
                        <route type="links">21256 13966 14056 14057</route>
                    </leg>
                    <act type="work" link="14057" x="335957.065395" y="3128105.16619" start_time="08:04:00" end_time="10:28:00" />
                    <leg mode="car" dep_time="10:28:00" trav_time="00:06:41" arr_time="10:34:41">
                        <route type="links">14057 14049 14045 13977 13939 13940 14050 14105 14114 21191</route>
                    </leg>
                    <act type="social" link="21191" x="333032.807855" y="3128759.66141" start_time="10:33:00" end_time="11:52:00" />
                    <leg mode="car" dep_time="11:52:00" trav_time="00:09:12" arr_time="12:01:12">
                        <route type="links">21191 21194 14189 14195 14197 14210 14212 14234 14246 14215 14192 14178 14057 13967 21257 21256</route>
                    </leg>
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="11:59:00" end_time="12:11:00" />
                    <leg mode="car" dep_time="12:11:00" trav_time="00:05:10" arr_time="12:16:10">
                        <route type="links">21256 13966 14049 14045 13977 13939 13925 13919 13905 13906</route>
                    </leg>
                    <act type="social" link="13906" x="332302.159169" y="3127536.46778" start_time="12:17:00" end_time="13:30:00" />
                    <leg mode="car" dep_time="13:30:00" trav_time="00:05:30" arr_time="13:35:30">
                        <route type="links">13906 13907 13904 13918 13924 13938 13976 14044 21259 21256</route>
                    </leg>
                    <act type="home" link="21256" x="334598.361546" y="3126269.05167" start_time="13:36:00" end_time="26:59:00" />
                </plan>

            </person>

        <!-- ====================================================================== -->

        </population>

我需要将其转换为以下类似于表的结构

<?xml version="1.0" encoding="UTF-8"?>
1,10000061,home,21258,334867.243653,3126570.70778,03:00:00,15:07:00,ride,15:07:00,00:03:27,15:10:27
2,10000061,shop,13904,332634.86999,3127078.96383,15:12:00,16:21:00,car,16:21:00,00:09:44,16:30:44
3,10000061,shop,14129,331666.364904,3129306.48785,16:25:00,17:37:00,ride,17:37:00,00:09:46,17:46:46
4,10000061,home,21258,334867.243653,3126570.70778,17:45:00,26:59:00,,,,  
5,10000302,home,21256,334598.361546,3126269.05167,03:00:00,07:56:00,car,07:56:00,00:03:00,07:59:00
6,10000302,work,14057,335957.065395,3128105.16619,08:04:00,10:28:00,car,10:28:00,00:08:20,10:36:20
7,10000302,social,21191,333032.807855,3128759.66141,10:33:00,11:52:00,car,11:52:00,00:08:33,12:00:33
8,10000302,home,21256,334598.361546,3126269.05167,11:59:00,12:11:00,car,12:11:00,00:06:35,12:17:35
9,10000302,social,13906,332302.159169,3127536.46778,12:17:00,13:30:00,car,13:30:00,00:05:30,13:35:30
10,10000302,home,21256,334598.361546,3126269.05167,13:36:00,26:59:00,,,,

目前,我正在使用下面显示的XSLT样式表,它给出了不同的格式。你能帮我修一下这个样式表来获得上述格式吗?

<xsl:stylesheet version="3.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs"
  expand-text="yes">
  <xsl:template name="xsl:initial-template">
    <xsl:stream href="100.plans.xml">
      <xsl:for-each select="/population/person | /population/person/plan[@selected='yes']/act | /population/person/plan[@selected='yes']/leg">
        {position()},{@id},{@type},{@link},{@x},{@y},{@start_time},{@end_time},{@mode},{@dep_time},{@trav_time},{@arr_time}
      </xsl:for-each>
    </xsl:stream>
  </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

这是一个流式采样,只使用Comparator<Player>将每个/population/person/plan[@selected='yes']及其祖先拉入内存,因为我认为不可能以纯流方式访问兄弟:

snapshot()

Saxon 9.7 EE的样本输入输出

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    expand-text="yes">

    <xsl:output method="text"/>

    <xsl:template name="xsl:initial-template">
        <xsl:stream href="100.plans.xml">
            <xsl:for-each select="/population/person/plan[@selected='yes']/snapshot()/act">
                <xsl:variable name="leg" select="following-sibling::*[1][self::leg]" />
                <xsl:value-of select="position(), ../../@id, @type, @link, @x, @y, @start_time, @end_time, string($leg/@mode), string($leg/@dep_time), string($leg/@trav_time), string($leg/@arr_time)" separator=","/>
                <xsl:text>&#10;</xsl:text>
            </xsl:for-each>
        </xsl:stream>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

看起来您实际上想要为每个act元素输出一行,但该行还将包含来自祖先personleg个节点的信息。这意味着你xsl:for-each应该是这样的:

<xsl:for-each select="/population/person/plan[@selected='yes']/act">

要获取person元素的ID,您可以执行此操作...

{../../@id}

要从以下leg元素获取信息,您可以定义一个类似的变量...

 <xsl:variable name="leg" select="following-sibling::*[1][self::leg]" />

然后你要从leg获取信息,你会这样做

{$leg/@mode}

我没有XSLT 3.0处理器来测试自己,但是在XSLT 1.0中,它看起来像这样(我没有包括所有字段以使它更短)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:template match="/">
      <xsl:for-each select="/population/person/plan[@selected='yes']/act">
        <xsl:variable name="leg" select="following-sibling::*[1][self::leg]" />
        <xsl:value-of select="position()" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="../../@id" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@type" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$leg/@mode" />
        <xsl:text>&#10;</xsl:text>
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

编辑:如果所有act元素确实存在除最后一个元素之外的leg个元素,请尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:template match="/">
      <xsl:for-each select="/population/person/plan[@selected='yes']/*[self::act|self::leg]">
        <xsl:choose>
          <xsl:when test="self::act">
            <xsl:value-of select="position()" />
            <xsl:text>,</xsl:text>
            <xsl:value-of select="../../@id" />
            <xsl:text>,</xsl:text>
            <xsl:value-of select="@type" />
            <xsl:text>,</xsl:text>
            <xsl:value-of select="@link" />
          </xsl:when>
          <xsl:when test="self::leg">
            <xsl:text>,</xsl:text>
            <xsl:value-of select="@mode" />
            <xsl:text>,</xsl:text>
            <xsl:value-of select="@dep_time" />
            <xsl:text>&#10;</xsl:text>
          </xsl:when>
        </xsl:choose>
      </xsl:for-each>
      <xsl:text>,,&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>