XSLT 使用 xslt 2.0 或更高版本将纯文本文件处理为 XML

Posted

技术标签:

【中文标题】XSLT 使用 xslt 2.0 或更高版本将纯文本文件处理为 XML【英文标题】:XSLT to process plain text file to XML using xslt 2.0 or higher 【发布时间】:2021-04-19 10:43:53 【问题描述】:

我正在与使用“Workday”ERP 的客户合作。该 ERP 主要处理 XML、XSLT 和 XSD 脚本,但不处理其他编程语言来转换数据进出 ERP。

我有一个固定长度的文本文件(示例如下),我正在尝试将其转换为 XML 以便在我的代码中进行进一步处理。我一直使用 XSLT 将 xml 转换为 xml (OR) xml 转换为文本,但反之则不然。

您能否指导我或提供一个示例 XSLT(2.0 或 3.0)以将以下文本数据转换为目标 XML(如下)。

输入定长文件:(第一个字符为记录类型,X,H为表头,最后的T,F为尾。每条Employee记录以1条E记录开头,后接多条W记录和B记录(可选)) .

X T3.03Q2020320201029015631AACW2                                                                                                                               xxxxxxx                  2020xx                            090420                                
H ZXCV          20200930      ABCABCA ABCABC                                     
E ******13662       372022456           Tony             B                StarkS              99999 Heritage Pkwy                                         zzzzzz                        MI48092                   YNNNMS19960706        19720724               PM                                 99999 Heritage Pkwy                                                             zzzzzz                        MI48092             
WW_SWW26                            61322         1524206         1442835         1442835               0               0               0               0             0               0            215611         5342667         5073153         5073153                               0               0                               0                          NN                 0               0   N  N       0000000000YYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
WW_CITYR2665440                      9192          972143          919215          919215               0               0               0               0             0               0              9192          972143          919215          919215                               0               0                               0                          NN                 0               0   N  N       0000000000NYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
BW_OASFEDERAL                       93217         1524206         1503506         1503506               0               0               0               0             0               0            327181         5342667         5277117         5277117                               0               0                               0                          NN                 0               0   N  N       0000000000YYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
E ******10665       362022493           Thor             S                Asar                2323 Clyde Road                                             Highzzzz                      MI48357                   YNNNMS19990517        19760301               PM                                 2323 Clyde Road                                                                 Highzzzz                      MI48357             
WW_SWW26                            61322         1524206         1442835         1442835               0               0               0               0             0               0            215611         5342667         5073153         5073153                               0               0                               0                          NN                 0               0   N  N       0000000000YYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
WW_CITYR2665440                      9192          972143          919215          919215               0               0               0               0             0               0              9192          972143          919215          919215                               0               0                               0                          NN                 0               0   N  N       0000000000NYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
BW_OASFEDERAL                       93217         1524206         1503506         1503506               0               0               0               0             0               0            327181         5342667         5277117         5277117                               0               0                               0                          NN                 0               0   N  N       0000000000YYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
BW_OASFEDERAL                       93217         1524206         1503506         1503506               0               0               0               0             0               0            327181         5342667         5277117         5277117                               0               0                               0                          NN                 0               0   N  N       0000000000YYY 14  440            0             0             0             0             0   0N                                                                                                                                                                                                                                      
T        39384       1699589934 
F        43442       1854024842 

预期的 XMl 输出如下所示:

<?xml version='1.0' encoding='utf-8'?>
<File>
    <X_Header></X_Header>
    <H_Header></H_Header>
    <All_Employees>
        <Employee>
            <E_record></E_record>
            <W_record></W_record>
            <W_record></W_record>
            <W_record></W_record>
            <B_record></B_record>
        </Employee>
        <Employee>
            <E_record></E_record>
            <W_record></W_record>
            <W_record></W_record>
            <W_record></W_record>
            <B_record></B_record>
        </Employee>
    </All_Employees>
    <T_Trailer></T_Trailer>
    <F_Trailer></F_Trailer>
</File>

【问题讨论】:

在 XSLT 2 中,您可以使用 unparsed-text XPath 2 函数将文本文件读入字符串,在 XSLT 3 中,您还可以使用 unparsed-text-lines 作为函数,以在文本文件中读取表示线条的字符串序列。在这种情况下,您通常使用命名模板开始处理(例如,XSLT 2 中的 &lt;xsl:template name="main"&gt;...&lt;/xsl:template&gt; 或 XSLT 3 中使用预定义的 &lt;xsl:template name="xsl:initial-template"&gt;...&lt;/xsl:template&gt;。要进一步分解字符串,请使用 tokenize 函数和/或 analyze-string 函数或xsl:analyze-string 指令。 【参考方案1】:

所以 XSLT 3 代码可以使用例如

  <xsl:param name="lines" select="unparsed-text-lines('file.txt')"/>
  
  <xsl:template match=".[. instance of xs:string]" mode="header">
      <xsl:element name="substring(., 1, 1)_Header">
          <xsl:apply-templates select="tokenize(., '\s+')" mode="data"/>
      </xsl:element>
  </xsl:template>
  
  <xsl:template match=".[. instance of xs:string]" mode="trailer">
      <xsl:element name="substring(., 1, 1)_Trailer">
          <xsl:apply-templates select="tokenize(., '\s+')" mode="data"/>
      </xsl:element>
  </xsl:template>
  
  <xsl:template match=".[. instance of xs:string]">
      <xsl:element name="substring(., 1, 1)_Record">
          <xsl:apply-templates select="tokenize(., '\s+')" mode="data"/>
      </xsl:element>
  </xsl:template>
  
  <xsl:template match="." mode="data" expand-text="yes">
      <Data>.</Data>
  </xsl:template>

  <xsl:template match="/" name="xsl:initial-template">
    <File>
        <xsl:apply-templates mode="header" select="$lines[starts-with(., 'H') or starts-with(., 'X')]"/>
        <All_Employees>
            <xsl:for-each-group select="$lines[not(matches(., '^[HXTF]'))]" group-starting-with=".[starts-with(., 'E')]">
                <Employee>
                    <xsl:apply-templates select="current-group()"/>
                </Employee>
            </xsl:for-each-group>
        </All_Employees>
        <xsl:apply-templates mode="trailer" select="$lines[starts-with(., 'T') or starts-with(., 'F')]"/>
    </File>
  </xsl:template>

您尚未详细说明如何解析每一行,但您可以轻松调整标记化和模板。

【讨论】:

以上是关于XSLT 使用 xslt 2.0 或更高版本将纯文本文件处理为 XML的主要内容,如果未能解决你的问题,请参考以下文章

Emacs nXML 模式中的 XSLT 2.0 支持

.NET 的 XPath 和 XSLT 2.0? [关闭]

使用 XSLT 2.0/3.0 使用多个步骤将 CDATA 中的纯文本解析为 html。那里的一部分

BizTalk Server 2016 映射中是不是支持 XSLT 2.0 或 3.0?

xslt 2.0:使用HashMap

哪些浏览器支持 XSLT 2.0?