我正在尝试转换这个XML
<params>
<param>
<name>parameter 1</name>
<type>values</type>
<values>"10""","20""","30""","40"""</values>
<param>
<param>
<name>parameter 2</name>
<type>values</type>
<values>100mm,200mm,300mm,400mm</values>
<param>
</params>
到该XML
<params>
<param>
<name>parameter 1</name>
<type>values</type>
<values>
<value>
<name><![CDATA[10"]]></name>
<value>
<value>
<name><![CDATA[20"]]></name>
<value>
<value>
<name><![CDATA[30"]]></name>
<value>
<value>
<name><![CDATA[40"]]></name>
<value>
</values>
<param>
<param>
<name>parameter 2</name>
<type>values</type>
<values>
<value>
<name><![CDATA[100mm]]></name>
<value>
<value>
<name><![CDATA[200mm]]></name>
<value>
<value>
<name><![CDATA[300mm]]></name>
<value>
<value>
<name><![CDATA[400mm]]></name>
<value>
</values>
<param>
</params>
使用此XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:output method="xml" />
<xsl:template match="/">
<params>
<xsl:apply-templates/>
</params>
</xsl:template>
<xsl:template match="params/param">
<param>
<name><xsl:value-of select="name" /></name>
<type><xsl:value-of select="type" /></type>
<values>
<xsl:call-template name="tokenize">
<xsl:with-param name="pText" select="values"/>
</xsl:call-template>
</values>
</param>
</xsl:template>
<!-- tokenize -->
<xsl:template name="tokenize">
<xsl:param name="pText"/>
<xsl:if test="string-length($pText)">
<value>
<name>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="substring-before($pText, '","')" />
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</name>
</value>
<xsl:call-template name="tokenize">
<xsl:with-param name="pText" select="substring-after($pText, '","')" />
</xsl:call-template>
</xsl:if>
</xsl:template>
我有几个问题:
最后一个值为空
我不知道如何删除第一个和最后一个报价
>
<values>
<value>
<name><![CDATA["10""]]></name>
</value>
<value>
<name><![CDATA[20""]]></name>
</value>
<value>
<name><![CDATA[30""]]></name>
</value>
<value>
<name><![CDATA[]]></name>
</value>
</values>
- 值在两个版本中都是以字符串形式表示的,我不知道如何编写条件来决定在标记化中使用哪个分隔符
我需要做这样的事情:
if (first char = ")
trim " from begining and end
split string by ","
foreach value replace "" to "
else
explode string by ,
但是我不知道如何使用XSLT来做到这一点。
你能给我建议吗?
我建议你这样尝试:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata-section-elements="name"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="values">
<xsl:copy>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="','"/>
<xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:if test="$token">
<value>
<name>
<xsl:choose>
<xsl:when test="starts-with($token, '"') and substring($token, string-length($token)) = '"'">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring($token, 2, string-length($token) - 2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$token"/>
</xsl:otherwise>
</xsl:choose>
</name>
</value>
</xsl:if>
<xsl:if test="contains($text, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:param name="searchString">""</xsl:param>
<xsl:param name="replaceString">"</xsl:param>
<xsl:choose>
<xsl:when test="contains($text,$searchString)">
<xsl:value-of select="substring-before($text,$searchString)"/>
<xsl:value-of select="$replaceString"/>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring-after($text,$searchString)"/>
<xsl:with-param name="searchString" select="$searchString"/>
<xsl:with-param name="replaceString" select="$replaceString"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>