创建通用XSLT以将文本文件解析为XML

时间:2016-01-21 19:14:09

标签: xslt-2.0 text-parsing

我被分配了一项任务,使用XSLT将大量文本文件转换为不同的XML。因为我对此非常陌生,所以我自己动了一下。这就是我发现可以解决的问题:1)XSLT在v2.0中开始支持这一点,以及2)未解析的文本( )是要走的路

所以我终于让它将文件解析为XML,但我使用的方法要求我每个文本文件(1到1)都有一个XSLT文件,因为需要对xsl这样的函数进行大量的硬编码: analyze-string我现在正试图找到一种方法,可以用一个通用的XSLT解析我的所有文件。请注意,文本文件可能包含不同的模式,但如果我能找到一种方法来一般地解析多个文件(具有相似的模式),那么我会很高兴。

以下是我的2个示例文件:

***********
* Sample1
***********

SET:              <block>    

      NAME:  Name1      <string>       /* some words/words */

!---end---        </block>    

SET:          <block>    
      NAME:   Name2     <string>    

      NESTEDSET:            <block>    
         VALUE1:    FIRST       <string>    
      ---end---

      NESTEDSET:            <block>    
         VALUE1:    SECOND      <string>    
         VALUE2:        ANYVALUE    <string>    
      ---end---

!---end---        </block>    

及以下是第二个样本文件

**********
* Sample2
**********

NEW_SET: <block> 
  NAME: Set1                <string>
*        Col1  Col2  Col3   
  ENTRY: 1     Win   0.2       <integer,string,floating>
  ENTRY: 2     Win   0.3       <integer,string,floating>       
  ENTRY: 3     Lost  0.4       <integer,string,floating>       

!--- end of block ---                  </block>

这是我为sample1创建的xslt:

<?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"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="sourcefile" 
        select="unparsed-text('file:///C:/Users/aUser/Desktop/Sample1.txt')"/>

    <xsl:template name="text2xml">
        <xsl:analyze-string select="translate(normalize-space($sourcefile), ' ',',')"         
            regex="SET:.*?!---end---" flags="s">
            <xsl:matching-substring>
                <SET>
                    <xsl:analyze-string select="." regex="(NAME):,([^,]*)">
                        <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:analyze-string select="." 
                        regex="NESTEDSET.*?,---end---" flags="s">
                        <xsl:matching-substring>
                            <NESTEDSET>
                                <xsl:analyze-string select="." 
                                    regex="(VALUE1|VALUE2):,([^,]*)">
                                    <xsl:matching-substring>
                                        <xsl:element name="{(regex-group(1))}">
                                            <xsl:value-of select="(regex-group(2))"/>
                                        </xsl:element>          
                                    </xsl:matching-substring>
                                </xsl:analyze-string>
                            </NESTEDSET>
                        </xsl:matching-substring>
                    </xsl:analyze-string> 
                </SET>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:template>  

    <xsl:template match="/">
        <xsl:call-template name="text2xml"/>    
    </xsl:template>

</xsl:stylesheet>

此xslt的xml输出为:

<?xml version="1.0" encoding="UTF-8"?>
<SET>
   <NAME>Name1</NAME>
</SET>
<SET>
   <NAME>Name2</NAME>
   <NESTEDSET>
      <VALUE1>FIRST</VALUE1>
   </NESTEDSET>
   <NESTEDSET>
      <VALUE1>SECOND</VALUE1>
      <VALUE2>ANYVALUE</VALUE2>
   </NESTEDSET>
</SET>

请问是否有更好的方法可以做到这一点?不硬编码任何东西,可以创建一些通用的东西,可以使用包含相同模式的其他文件? 我这样做的方式(根据我的理解)是我使用unparsed-text()将文本文件强制为单行,然后对字符串进行硬编码(在正则表达式中)以告诉它在哪里开始/停止查找。所以只想找一个更好的方法。 感谢大家的任何建议/反馈。

0 个答案:

没有答案