xslt 是将文本转换为 xml 结构的好方法吗?

2023-12-03

我正在尝试找到一个更好的解决方案来将纯文本(但每个字段具有预定义的长度)转换为 xml。 例如输入文本可以是 “Testuser new york 10018”,前 11 个字符表示用户名,接下来的 12 个字符表示城市,接下来的 5 个字符表示邮政编码。 所以我需要从上面的字符串中形成一个具有预定义字段长度的 xml。

我正在考虑两种方法

  1. 定义业务实体并通过对输入文本使用子字符串函数填充实体属性,然后将实体序列化为 xml

  2. 预定义xml结构,使用xslt导航到每个节点并通过以下方式填充值 对输入文本使用子字符串函数。


声明:(XSLT)"isn't suitable for transforming from structured text to XML. "和声明"XSLTmusthave XML as the input document"**都是错误的.

我正在考虑两种方法

  1. 定义一个业务实体并通过在输入文本上使用子字符串函数填充实体属性,然后将该实体序列化为 XML

  2. 预定义 xml 结构,使用 xslt 导航到每个节点并通过在输入文本上使用子字符串函数来填充值。

事实上,方法 2 使用 XSLT 很容易实现:

一、XSLT 1.0:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*/text()" name="processLines">
  <xsl:param name="pText" select="."/>

  <xsl:if test="contains($pText, '&#xA;')">
    <xsl:variable name="vLine" select=
     "substring-before($pText, '&#xA;')"/>

     <user>
       <name>
         <xsl:value-of select=
         "translate(substring-before($vLine, ' '),'_',' ')"/>
       </name>
       <city>
         <xsl:value-of select=
         "translate(substring-before(substring-after($vLine, ' '),' '),
                    '_',
                    ' '
                    )
         "/>
       </city>
       <zipCode>
         <xsl:value-of select=
         "translate(substring-after(substring-after($vLine, ' '),' '),
                    '_',
                    ' '
                    )
         "/>
       </zipCode>
     </user>

     <xsl:call-template name="processLines">
      <xsl:with-param name="pText" select=
      "substring-after($pText, '&#xA;')"/>
     </xsl:call-template>
  </xsl:if>
  </xsl:template>
</xsl:stylesheet>

当此转换应用于特殊格式的文本时(包装在单个顶部元素中以使其格式良好 - 正如我们将在 XSLT 2.0 中看到的那样,这种包装是不必要的):

<t>Testuser new_york 10018
usera seattle 98000
userb bellevue 98004
userb redmond 98052
</t>

产生了想要的结果:

<user>
   <name>Testuser</name>
   <city>new york</city>
   <zipCode>10018</zipCode>
</user>
<user>
   <name>usera</name>
   <city>seattle</city>
   <zipCode>98000</zipCode>
</user>
<user>
   <name>userb</name>
   <city>bellevue</city>
   <zipCode>98004</zipCode>
</user>
<user>
   <name>userb</name>
   <city>redmond</city>
   <zipCode>98052</zipCode>
</user>

Notes:

  1. 这只是一个演示如何完成任务的演示。这就是为什么我不处理固定宽度字段(虽然会更容易),而是处理空格分隔的值。

  2. 任何值中包含的任何空格都作为下划线(或我们选择的任何字符,我们知道它们永远不会成为任何值的一部分)输入到输入中。在输出时,任何下划线都会转换为真实的空格。

二. XSLT 2.0 解决方案:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vText" select=
  "unparsed-text('file:///c:/temp/delete/delete.txt')"/>

 <xsl:variable name="vLines" select=
  "tokenize($vText, '&#xD;?&#xA;')[normalize-space()]"/>

 <xsl:template match="/">
  <xsl:for-each select="$vLines">
    <xsl:variable name="vFields" select=
    "tokenize(., ' ')[normalize-space()]"/>
   <user>
     <name>
       <xsl:sequence select="translate($vFields[1], '_',' ')"/>
     </name>
     <city>
       <xsl:sequence select="translate($vFields[2], '_',' ')"/>
     </city>
     <zipCode>
       <xsl:sequence select="translate($vFields[3], '_',' ')"/>
     </zipCode>
   </user>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于任何 XML 文档时(未使用且实际上不需要,因为在 XSLT 2.0 中不需要源 XML 文档),并且如果文件C:\temp\delete\delete.txt is:

Testuser new_york 10018
usera seattle 98000
userb bellevue 98004
userb redmond 98052

再次产生想要的正确结果:

<user>
   <name>Testuser</name>
   <city>new york</city>
   <zipCode>10018</zipCode>
</user>
<user>
   <name>usera</name>
   <city>seattle</city>
   <zipCode>98000</zipCode>
</user>
<user>
   <name>userb</name>
   <city>bellevue</city>
   <zipCode>98004</zipCode>
</user>
<user>
   <name>userb</name>
   <city>redmond</city>
   <zipCode>98052</zipCode>
</user>

Notes:

  1. 使用标准 XSLT 2.0 函数unparsed-text().

  2. 使用标准 XPath 2.0 函数tokenize().

最后说明:

最复杂的文本处理完全以 XSLT 的工业方式完成。FXSL 库包含一个通用的LR(1) 解析器 and a 调整 YACC 以生成 XML 格式的表这是这个通用运行时 LR(1) 解析器的输入。

使用这个工具我成功了内置解析器对于 JSON 和 XPath 2.0 等复杂语言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

xslt 是将文本转换为 xml 结构的好方法吗? 的相关文章

随机推荐