Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.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
Xml 在XSLT中拆分逗号分隔的字段,并选择或限制字段数_Xml_Xslt_Xpath - Fatal编程技术网

Xml 在XSLT中拆分逗号分隔的字段,并选择或限制字段数

Xml 在XSLT中拆分逗号分隔的字段,并选择或限制字段数,xml,xslt,xpath,Xml,Xslt,Xpath,我希望包含来自CSV格式的XML元素的数据 <xsl:template name="cvsmaxkey"> <xsl:param name="keys" /> <xsl:param name="nrofkeys" /> <xsl:param name="pos" /> <xsl:if test="$pos &lt;= $nrofkeys"> <xsl:if test="$p

我希望包含来自CSV格式的XML元素的数据

<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>
讽刺的是,输出是一个CSV文件

<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>
真正的问题是CSV格式允许4个关键字

,,,,,,one,two,three,four,,,,,,     OK
,,,,,,one,two,three,four,five,,,,, WRONG
,,,,,,one,two,,,,,,,,              OK
,,,,,,,,,,,,,,,                    OK
<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>
因此,通常的可疑
不起作用,因为元素中的值的数量是可变的,通常为无,有时为3到5个条目

<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>
比如

<keywords>one,two,three,four</keywords>
<keywords>one,two,three,four,five</keywords>
<keywords>one,two</keywords>
<keywords></keywords>
<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>
1,2,3,4
一,二,三,四,五
一,二
是否有任何方法可以使用XSLT将此CSV数组转换为XML元素,然后以每个元素为目标。空值就可以了

<xsl:value-of select="fubar1"/><xsl:value-of select="','"/>
<xsl:value-of select="keyword[1]"/><xsl:value-of select="','"/>
<xsl:value-of select="keyword[2]"/><xsl:value-of select="','"/>
<xsl:value-of select="keyword[3]"/><xsl:value-of select="','"/>
<xsl:value-of select="keyword[4]"/><xsl:value-of select="','"/>
<xsl:value-of select="fubar3"/><xsl:value-of select="','"/>
<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>

I.这里有一个简单的XSLT2.0解决方案:

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

 <xsl:template match="text()">
   <xsl:value-of select=
    "tokenize(., ',')[.][not(position() gt 4)]" separator=","/>
    <xsl:text>&#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>
one,two,three,four
one,two,three,four
one,two
<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>

II。非递归XSLT 1.0解决方案

<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>
此XSLT 1.0转换

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vDoc" select="document('')"/>

 <xsl:variable name="vNodes"
   select="$vDoc//node() | $vDoc//@* | $vDoc//namespace::*"/>

 <xsl:template match="text()">
    <xsl:variable name="vNorm" select="normalize-space(translate(.,',',' '))"/>
    <xsl:variable name="vCount" select=
    "string-length($vNorm) -string-length(translate($vNorm, ' ', ''))+1"/>

    <xsl:variable name="vTextToPrint">
        <xsl:choose>
          <xsl:when test="not($vCount >4)"><xsl:value-of select="$vNorm"/></xsl:when>
          <xsl:otherwise>
            <xsl:for-each select="$vNodes[not(position() > string-length($vNorm))]">
              <xsl:variable name="vPos" select="position()"/>
              <xsl:variable name="vheadSubstr" select="substring($vNorm,1,$vPos)"/>
              <xsl:if test=
              "substring($vNorm, $vPos, 1) = ' '
              and
                string-length($vheadSubstr)
               -
                string-length(translate($vheadSubstr, ' ',''))

                = 4">
                <xsl:value-of select="substring($vNorm,1,$vPos -1)"/>
              </xsl:if>
            </xsl:for-each>
          </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:value-of select="translate($vTextToPrint, ' ', ',')"/>
    <xsl:text>&#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>
one,two,three,four
one,two,three,four
one,two
<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>

这里是一个简单的递归版本:

<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>

<xsl:template name="cvsmaxkey">
    <xsl:param name="keys" />
    <xsl:param name="nrofkeys" /> 
    <xsl:param name="pos" />
    <xsl:if test="$pos &lt;= $nrofkeys">
        <xsl:if test="$pos > 1 and $keys">
            <xsl:value-of select="','" />
        </xsl:if>
        <xsl:choose>
            <xsl:when test="contains($keys, ',')">
                <xsl:value-of select="substring-before($keys,',')" />
                <xsl:call-template name="cvsmaxkey">
                    <xsl:with-param name="keys" select="substring-after($keys,',')" />
                    <xsl:with-param name="nrofkeys" select="$nrofkeys" />
                    <xsl:with-param name="pos" select="$pos +1" />
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$keys">
                <xsl:value-of select="$keys" />
                <xsl:value-of select="substring(',,,,,,,,,,,', 1,$nrofkeys - $pos)"/>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="keywords">
    <xsl:call-template name="cvsmaxkey">
        <xsl:with-param name="keys" select="." />
        <xsl:with-param name="nrofkeys" select="4" />
        <xsl:with-param name="pos" select="1" />
    </xsl:call-template>
    <xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="/">
    <xsl:apply-templates select="//keywords"/>
</xsl:template>

不清楚您的XML数据是什么样子的。是“如”后面的示例,还是输出?如果您的输入在XML元素中有CSV数据字段,那么听起来您想要使用XSLT做的事情是可能的,但是我更喜欢使用脚本语言来实现这一点。您是否依赖XSLT?首先,非常感谢xml先生。2.0解决方案非常简单,易于遵循。但我必须使用令人困惑的1.0。如何应用一个典型的xml数据,例如@user1869322中的NameAddressone、two、three、four、fivecityxxx,请在提供的xml文档上使用提供的XSLT1.0转换调用XSLT1.0处理器。然后您将得到提供的结果。是的。这很有效。非常感谢。我需要把那些多余的逗号填上。也就是说,不是一,二,而是一,二,@user1869322,不客气。额外的逗号可以在单独的(或其他)指令中输出。就像水力压裂的魅力一样。而且易于实现。它似乎受到
中逗号数量的限制,但在大多数情况下都可以。干杯