2010-06-30 62 views
0

我仍然是XSLT的初学者,但我手头有一项艰巨的任务。复杂的XSL转换

我有一个非xml文件,需要进行转换。该文件的格式A S如下:

type1 
type1line1 
type1line2 
type1line3 
type2 
type2line1 
type2line2 
type3 
type3line1 
type3line2 

类型(type1, type2, ...)使用不具有特定的顺序某些代码指定。下面的每种类型都有多个line

所以,我需要转换这个文件,但问题是,对于每个type我必须为它的每个底层线做不同的转换。

现在,我可以逐行读取字符串,并确定一个新类型已经开始,但我不知道如何设置一个标志(指示类型)在底层行中使用它。

这是我现在所拥有的:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0"> 
    <xsl:param name="testString" as="xs:string"> 
    type1 
    line1 
    line2 
    type1 
    line1 
    </xsl:param> 
    <xsl:template match="/"> 
    <xsl:call-template name="main"> 
     <xsl:with-param name="testString" select="$testString"/> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="main"> 
    <xsl:param name="testString"/> 
    <xsl:variable name="iniFile" select="$testString"/> 
    <config> 
     <xsl:analyze-string select="$iniFile" regex="\n"> 
     <xsl:non-matching-substring> 
      <item> 
      <xsl:choose> 
       <xsl:when test="starts-with(., 'type1')"> 
    <!-- do a specific transformation-->  
       </xsl:when> 
       <xsl:when test="starts-with(., 'type2')"> 
    <!-- do another transformation-->  
       </xsl:when> 
      </xsl:choose> 
      </item> 
     </xsl:non-matching-substring> 
     </xsl:analyze-string> 
    </config> 
    </xsl:template> 
</xsl:stylesheet> 

关于如何解决这个问题的任何想法。

+1

你一定要明白XSLT是为了转换** XML文件**? ;) – 2010-06-30 13:13:50

+1

将此问题标记为XSLT2以避免像Niels'这样的评论。 @Niels van der Rest:XSLT2可以处理未解析的文档。 – 2010-06-30 13:28:57

+0

@Alejandro感谢您纠正我,我没有意识到这一点:) – 2010-06-30 13:34:35

回答

0

我认为XSLT 2.1将允许您使用像for-each-group这样的强大的东西来处理像字符串这样的原子值序列,但是对于XSLT 2.0,只有节点序列才具有如此强大的功能,所以我第一步使用XSLT 2.0使用纯数据字符串我想处理/组是创建元素。因此,您可以对数据进行标记,将每个标记包装到某个元素中,然后使用for-each-group group-starting-with来处理每个组,并以'^ type [0-9] + $'之类的模式开始。 你还没有真正告诉我们你想用什么样的数据,一旦你已经确定了一个组,以便采取以下作为例如,你可以适应:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs"> 

    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="input" as="xs:string">type1 
type1line1 
type1line2 
type1line3 
type2 
type2line1 
type2line2 
type3 
type3line1 
type3line2</xsl:param> 

    <xsl:template name="main"> 
    <xsl:variable name="lines" as="element(item)*"> 
     <xsl:for-each select="tokenize($input, '\n')"> 
     <item><xsl:value-of select="."/></item> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:for-each-group select="$lines" group-starting-with="item[matches(., '^type[0-9]+$')]"> 
     <xsl:choose> 
     <xsl:when test=". = 'type1'"> 
      <xsl:apply-templates select="current-group() except ." mode="m1"/> 
     </xsl:when> 
     <xsl:when test=". = 'type2'"> 
      <xsl:apply-templates select="current-group() except ." mode="m2"/> 
     </xsl:when> 
     <xsl:when test=". = 'type3'"> 
      <xsl:apply-templates select="current-group() except ." mode="m3"/> 
     </xsl:when> 
     </xsl:choose> 
    </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template match="item" mode="m1"> 
    <foo> 
     <xsl:value-of select="."/> 
    </foo> 
    </xsl:template> 

    <xsl:template match="item" mode="m2"> 
    <bar> 
     <xsl:value-of select="."/> 
    </bar> 
    </xsl:template> 

    <xsl:template match="item" mode="m3"> 
    <baz> 
     <xsl:value-of select="."/> 
    </baz> 
    </xsl:template> 

</xsl:stylesheet> 

当撒克逊9(命令行选项适用-IT :主要-xsl:sheet.xsl)的结果是

<foo>type1line1</foo> 
<foo>type1line2</foo> 
<foo>type1line3</foo> 
<bar>type2line1</bar> 
<bar>type2line2</bar> 
<baz>type3line1</baz> 
<baz>type3line2</baz>