Обычный текстовый файл в XML с использованием XSLT - PullRequest
9 голосов
/ 15 апреля 2011

У меня есть текстовый файл, который выглядит так:

XXX^YYYY^AAAAA^XXXXXX^AAAAAA....

Поля разделены с помощью каретки (^), мои предположения:

первое поле = NAMEвторое поле = Фамилиятретье поле = адрес

и т. д.

Я хотел бы превратить его в действительный XML с использованием xsl (XSLT).например:

<name>XXX</name>
<l_name>YYYY</l_name>

Я знаю, что это легко сделать с помощью Perl, но мне нужно сделать это с XSLT, если это возможно.

Ответы [ 2 ]

10 голосов
/ 15 апреля 2011

Текстовые (не XML) файлы могут быть прочитаны с помощью стандартной функции XSLT 2.0 unparsed-text().

Тогда можно использовать стандартную функцию XPath 2.0 tokenize() и две другие стандартные функции XPath 2.0, которые принимают регулярные выражения в качестве одного из аргументов - matches() и replace().

XSLT 2.0 имеет собственные мощные инструкции для обработки текста с использованием регулярных выражений: : <xsl:analyze-string>, <xsl:matching-substring> и <xsl:non-matching-substring> инструкция.

См. Некоторые из более мощных возможностей обработки текста XSLT с этими функциями и инструкциями в этом реальном примере: XSLT решение проблемы WideFinder .

Наконец, вот решение XSLT 1.0 :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
 xmlns:my="my:my" exclude-result-prefixes="ext my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <my:fieldNames>
  <name>FirstName</name>
  <name>LastName</name>
  <name>City</name>
  <name>State</name>
  <name>Zip</name>
 </my:fieldNames>

 <xsl:variable name="vfieldNames" select=
  "document('')/*/my:fieldNames"/>

 <xsl:template match="/">
  <xsl:variable name="vrtfTokens">
   <xsl:apply-templates/>
  </xsl:variable>

  <xsl:variable name="vTokens" select=
       "ext:node-set($vrtfTokens)"/>

  <results>
   <xsl:apply-templates select="$vTokens/*"/>
  </results>
 </xsl:template>

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

     <xsl:if test="string-length($pText)">
       <xsl:variable name="vWord" select=
       "substring-before(concat($pText, '^'),'^')"/>

       <word>
        <xsl:value-of select="$vWord"/>
       </word>

       <xsl:call-template name="tokenize">
        <xsl:with-param name="pText" select=
         "substring-after($pText,'^')"/>
       </xsl:call-template>
     </xsl:if>
 </xsl:template>

 <xsl:template match="word">
  <xsl:variable name="vPos" select="position()"/>

  <field>
      <xsl:element name="{$vfieldNames/*[position()=$vPos]}">
      </xsl:element>
      <value><xsl:value-of select="."/></value>
  </field>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к следующему документу XML:

<t>John^Smith^Bellevue^WA^98004</t>

желаемый, правильный результат выдается :

<results>
   <field>
      <FirstName/>
      <value>John</value>
   </field>
   <field>
      <LastName/>
      <value>Smith</value>
   </field>
   <field>
      <City/>
      <value>Bellevue</value>
   </field>
   <field>
      <State/>
      <value>WA</value>
   </field>
   <field>
      <Zip/>
      <value>98004</value>
   </field>
</results>
1 голос
/ 15 апреля 2011

Токенизация и сортировка с помощью XSLT 1.0

Если вы используете xslt 2.0, это намного проще: fn: tokenize (string, pattern)

Example: tokenize("XPath is fun", "\s+")
Result: ("XPath", "is", "fun")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...