Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 对连续节点进行排序和连接_Sorting_Xslt_Xslt 1.0 - Fatal编程技术网

Sorting 对连续节点进行排序和连接

Sorting 对连续节点进行排序和连接,sorting,xslt,xslt-1.0,Sorting,Xslt,Xslt 1.0,我有一个大致如下的XML文件(实际文件要复杂得多,在本例中所有内容都被截断): 1. 东西 一串 东西 2. 东西 一串 日期 浮动 东西 3. 东西 日期时间 东西 4. 东西 浮动 一串 日期 东西 我使用以下XSLT处理它: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns

我有一个大致如下的XML文件(实际文件要复杂得多,在本例中所有内容都被截断):


1.
东西
一串
东西
2.
东西
一串
日期
浮动
东西
3.
东西
日期时间
东西
4.
东西
浮动
一串
日期
东西
我使用以下XSLT处理它:

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

    <xsl:template match="element">
        <xsl:element name="xs:element">
            <xsl:attribute name="type"><xsl:call-template name="type"/></xsl:attribute>
        </xsl:element>
    </xsl:template>

    <xsl:template name="type">
        <xsl:variable name="initialType" select="translate(type,' ','')"/>
        <xsl:choose>
            <xsl:when test="$initialType='String'">
                <xsl:text>xs:string</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Date'">
                <xsl:text>xs:date</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='DateTime'">
                <xsl:text>xs:dateTime</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Float'">
                <xsl:text>xs:float</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Integer'">
                <xsl:text>xs:int</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$initialType"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

xs:string
xs:日期
日期时间
浮动
xs:int
我得到了这个结果文件:

<?xml version="1.0" encoding="UTF-8"?>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string"/>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string"/>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:dateTime"/>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:float"/>

我这里的问题是只考虑第一个
标记。我想要的是将所有类型标记内容连接到输出的类型标记中,前面有一个符号指示标记是聚合的(如果适用)。 然而,为了避免人为地创建大量类型,标签的内容必须首先按字母顺序排序。在本例中,
数字2和4都仅由Float、String和Date组成,尽管顺序不同。它们需要在输出中具有相同的类型

可接受以下输出:

<?xml version="1.0" encoding="UTF-8"?>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:string"/>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="unionxs:datexs:floatxs:string"/>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="xs:dateTime"/>
    <xs:element xmlns:xs="http://www.w3.org/2001/XMLSchema" type="unionxs:datexs:floatxs:string"/>

我对XLST非常陌生,到目前为止,我还没有设法获得接近所需输出的任何地方。我试过的代码就在下面,失败得很惨,特别是因为我不明白如何让
工作:

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

    <xsl:template match="element">
        <xsl:element name="xs:element">
            <xsl:attribute name="type">
                    <xsl:apply-templates>
                      <xsl:sort select="."/>
                    </xsl:apply-templates>
                    <xsl:call-template name="type"/>
                </xsl:attribute>
        </xsl:element>
    </xsl:template>

    <xsl:template name="type">
        <xsl:choose>
            <xsl:when test="following-sibling::type">
                <xs:text>union</xs:text>
                <xsl:for-each select="following-sibling::type">
                    <xs:text>translate(type,' ','')</xs:text>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="initialType" select="translate(type,' ','')"/>
                <xsl:choose>
                    <xsl:when test="$initialType='String'">
                        <xsl:text>xs:string</xsl:text>
                    </xsl:when>
                    <xsl:when test="$initialType='Date'">
                        <xsl:text>xs:date</xsl:text>
                    </xsl:when>
                    <xsl:when test="$initialType='DateTime'">
                        <xsl:text>xs:dateTime</xsl:text>
                    </xsl:when>
                    <xsl:when test="$initialType='Float'">
                        <xsl:text>xs:float</xsl:text>
                    </xsl:when>
                    <xsl:when test="$initialType='Integer'">
                        <xsl:text>xs:int</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$initialType"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

联盟
翻译(类型,,“”)
xs:string
xs:日期
日期时间
浮动
xs:int

只需对现有代码进行一些调整

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="element">
        <xsl:element name="xs:element">
            <xsl:attribute name="type">
                <xsl:variable name="sorted">
                    <xsl:for-each select="type">
                        <xsl:sort select="."/>
                        <xsl:copy-of select="."/>    
                    </xsl:for-each>
                </xsl:variable>
                <xsl:apply-templates select="$sorted/type"/>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>

    <xsl:template match="type">
        <xsl:variable name="initialType" select="translate(., ' ', '')"/>
        <xsl:if test="count(preceding-sibling::type) = 0 and count(following-sibling::type) > 0">
            <xsl:text>union</xsl:text>
        </xsl:if>
        <!-- HINT remove if you dont want any seperator -->
        <xsl:if test="count(preceding-sibling::type) > 0">
            <xsl:text> </xsl:text>
        </xsl:if>
        <xsl:choose>
            <xsl:when test="$initialType='String'">
                <xsl:text>xs:string</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Date'">
                <xsl:text>xs:date</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='DateTime'">
                <xsl:text>xs:dateTime</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Float'">
                <xsl:text>xs:float</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Integer'">
                <xsl:text>xs:int</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$initialType"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

联盟
xs:string
xs:日期
日期时间
浮动
xs:int
请验证,我得到了输出(请参见XSLT中的提示内联):


只需对现有代码进行一些调整

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="element">
        <xsl:element name="xs:element">
            <xsl:attribute name="type">
                <xsl:variable name="sorted">
                    <xsl:for-each select="type">
                        <xsl:sort select="."/>
                        <xsl:copy-of select="."/>    
                    </xsl:for-each>
                </xsl:variable>
                <xsl:apply-templates select="$sorted/type"/>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>

    <xsl:template match="type">
        <xsl:variable name="initialType" select="translate(., ' ', '')"/>
        <xsl:if test="count(preceding-sibling::type) = 0 and count(following-sibling::type) > 0">
            <xsl:text>union</xsl:text>
        </xsl:if>
        <!-- HINT remove if you dont want any seperator -->
        <xsl:if test="count(preceding-sibling::type) > 0">
            <xsl:text> </xsl:text>
        </xsl:if>
        <xsl:choose>
            <xsl:when test="$initialType='String'">
                <xsl:text>xs:string</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Date'">
                <xsl:text>xs:date</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='DateTime'">
                <xsl:text>xs:dateTime</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Float'">
                <xsl:text>xs:float</xsl:text>
            </xsl:when>
            <xsl:when test="$initialType='Integer'">
                <xsl:text>xs:int</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$initialType"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

联盟
xs:string
xs:日期
日期时间
浮动
xs:int
请验证,我得到了输出(请参见XSLT中的提示内联):


我会这样做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="element">
        <xsl:element name="xs:element">
            <xsl:attribute name="type">
                <xsl:apply-templates select="type">
                    <xsl:sort select="."/>
                </xsl:apply-templates>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'String']">xs:string</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'Date']">xs:date</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'DateTime']">xs:dateTime</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'Float']">xs:float</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'Integer']">xs:int</xsl:template>

    <xsl:template match="type">
        <xsl:value-of select="translate(., ' ', '')"/>
    </xsl:template>

</xsl:stylesheet>

xs:string
xs:日期
日期时间
浮动
xs:int

我会这样做:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="element">
        <xsl:element name="xs:element">
            <xsl:attribute name="type">
                <xsl:apply-templates select="type">
                    <xsl:sort select="."/>
                </xsl:apply-templates>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'String']">xs:string</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'Date']">xs:date</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'DateTime']">xs:dateTime</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'Float']">xs:float</xsl:template>

    <xsl:template match="type[translate(., ' ', '') = 'Integer']">xs:int</xsl:template>

    <xsl:template match="type">
        <xsl:value-of select="translate(., ' ', '')"/>
    </xsl:template>

</xsl:stylesheet>

xs:string
xs:日期
日期时间
浮动
xs:int

这在我的示例文件中运行良好。但是,它并没有解决我的整个问题:第二个和第四个元素基本上共享相同的类型,但顺序不同,这导致它们在输出中具有不同的类型,这是不需要的。有没有办法在连接之前对类型进行排序?我添加了“the”/a排序。不客气。也许你可以将它与@Martin Honnen的解决方案合并。创建映射要优雅一点。由于某些原因,在简单示例文件上有效的东西在实际文件上不起作用。我会仔细考虑马丁的答案,并尝试将其与你的答案结合起来。尝试:在
+中添加
xmlns:msxsl=“urn:schemas microsoft com:xslt”
。还有一些其他的扩展。请看,这在我的示例文件中效果很好。但是,它并没有解决我的整个问题:第二个和第四个元素基本上共享相同的类型,但顺序不同,这导致它们在输出中具有不同的类型,这是不需要的。有没有办法在连接之前对类型进行排序?我添加了“the”/a排序。不客气。也许你可以将它与@Martin Honnen的解决方案合并。创建映射要优雅一点。出于某种原因,在