Sorting 对连续节点进行排序和连接
我有一个大致如下的XML文件(实际文件要复杂得多,在本例中所有内容都被截断):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
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的解决方案合并。创建映射要优雅一点。出于某种原因,在