应该使用XSLT 1.0将文本输入转换为XML输出。该列表的长度可变,定界符为|
。
输入:
name=IMON_EVENT;next_state=SET_IMON;is_enabled=true; | name=MAIN_BATCH;next_state=BATCH01;is_enabled=false;priority=9;
预期输出:
<time-triggers>
<trigger>
<name>IMON_EVENT</name>
<next_state>SET_IMON</next_state>
<is_enabled>true</is_enabled>
</trigger>
<trigger>
<name>MAIN_BATCH</name>
<next_state>BATCH01</next_state>
<is_enabled>false</is_enabled>
<priority>9</priority>
</trigger>
</time-triggers>
答案 0 :(得分:0)
对于 XSLT 1.0 ,您可以使用递归模板调用来测试分隔符的存在,并使用substring-before()
和substring-after()
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="triggers" select="'name=IMON_EVENT;next_state=SET_IMON;is_enabled=true; | name=MAIN_BATCH;next_state=BATCH01;is_enabled=false;priority=9;'"/>
<triggers>
<xsl:call-template name="make-trigger">
<xsl:with-param name="val" select="$triggers"/>
</xsl:call-template>
</triggers>
</xsl:template>
<xsl:template name="make-trigger">
<xsl:param name="val"/>
<xsl:if test="normalize-space($val)">
<xsl:choose>
<xsl:when test="contains($val, '|')">
<trigger>
<xsl:call-template name="make-elements">
<xsl:with-param name="val" select="substring-before($val, '|')"/>
</xsl:call-template>
</trigger>
<xsl:call-template name="make-trigger">
<xsl:with-param name="val" select="substring-after($val, '|')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<trigger>
<xsl:call-template name="make-elements">
<xsl:with-param name="val" select="$val"/>
</xsl:call-template>
</trigger>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="make-elements">
<xsl:param name="val"/>
<xsl:if test="contains($val, '=')">
<xsl:choose>
<xsl:when test="contains($val, ';')">
<xsl:call-template name="make-element">
<xsl:with-param name="val" select="substring-before($val, ';')"/>
</xsl:call-template>
<xsl:call-template name="make-elements">
<xsl:with-param name="val" select="substring-after($val, ';')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="make-element">
<xsl:with-param name="val" select="$val"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template name="make-element">
<xsl:param name="val"/>
<xsl:element name="{normalize-space(substring-before($val, '='))}">
<xsl:value-of select="substring-after($val, '=')"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
以下是 XSLT 2.0 解决方案,该解决方案使用tokenize()
函数将值|
和;
分隔符与嵌套的xsl:for-each
分隔为处理值的序列,xsl:analyze-string
捕获=
之间的名称和值,xsl:element
从正则表达式捕获组创建动态命名的元素。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="triggers" select="'name=IMON_EVENT;next_state=SET_IMON;is_enabled=true; | name=MAIN_BATCH;next_state=BATCH01;is_enabled=false;priority=9;'"/>
<triggers>
<xsl:for-each select="tokenize($triggers, '\s*\|\s*')">
<trigger>
<xsl:for-each select="tokenize(., '\s*;\s*')">
<xsl:analyze-string select="." regex="(.+)=(.*)">
<xsl:matching-substring>
<xsl:element name="{regex-group(1)}">
<xsl:value-of select="regex-group(2)"/>
</xsl:element>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</trigger>
</xsl:for-each>
</triggers>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
在XSLT脚本中放置源字符串是一种不好的做法, 尤其是如果您要处理各种输入。
如果可以使用XSLT 2.0版,则应该使用以下功能:
unparsed-text-available
-检查输入文件是否存在,unparsed-text
-将该文件的内容读入变量。脚本的其余部分(如何处理读取的内容)可以与其他答案相同。