Xslt 2 convert non-unique elements to attributes for grid

让人想犯罪 __ 提交于 2019-12-12 01:54:47

问题


I have an XML file with this structure

<levels>
  <level id="0" qd="NE">
    <gate>99</gate>
    <zone>2</zone>
    <laydown>4</laydown>
  </level>
  <level id="0" qd="SE">
    <gate>1</gate>
    <zone>6</zone>
    <laydown>1</laydown>
    <laydown>2</laydown>
    <laydown>3</laydown>
    <zone>5</zone>
    <zone>5</zone>
  </level>
</levels>

And I need to convert it to something like this to display in a grid

<level id="0" qd="NE" gate="99" zone="2"  laydown="3">
<level id="0" qd="NE" gate="1" zone="5,6" laydown="1,2,3">

I have found xslt that works but not where the elements are non-unique. They only pick up the LAST element suggesting that each element is overwriting the previous. Have not included it as I would rather see the proper solution than my bodged attempt just made to work. I am an xsl/xslt newbie so any annotation will be helpful. I work with vs 2013


回答1:


If you're creating an attribute for each element, it will definitely overwrite any previous attribute that you've created (with the same name).

You tagged this as XSLT 2.0, so here's a 2.0 option. The output doesn't match yours exactly; your example doesn't make a whole lot of sense in a couple of places. (Like why does the first level have laydown="3" instead of laydown="4" and both level's have qd="NE".)

XML Input

<levels>
    <level id="0" qd="NE">
        <gate>99</gate>
        <zone>2</zone>
        <laydown>4</laydown>
    </level>
    <level id="0" qd="SE">
        <gate>1</gate>
        <zone>6</zone>
        <laydown>1</laydown>
        <laydown>2</laydown>
        <laydown>3</laydown>
        <zone>5</zone>
        <zone>5</zone>
    </level>
</levels>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:local="local" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:function name="local:sort">
        <xsl:param name="seq"/>
        <xsl:perform-sort select="$seq">
            <xsl:sort data-type="number"/>
        </xsl:perform-sort>
    </xsl:function>

    <xsl:template match="level">
        <xsl:variable name="level" select="."/>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:for-each select="distinct-values(*/name())">
                <xsl:attribute name="{.}" 
                    select="string-join(distinct-values(local:sort($level/*[name()=current()])),',')"/>
            </xsl:for-each>
        </xsl:copy>        
    </xsl:template>

</xsl:stylesheet>

Output

<levels>
   <level id="0" qd="NE" gate="99" zone="2" laydown="4"/>
   <level id="0" qd="SE" gate="1" zone="5,6" laydown="1,2,3"/>
</levels>


来源:https://stackoverflow.com/questions/27528580/xslt-2-convert-non-unique-elements-to-attributes-for-grid

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!