2013-04-12 13 views
5

Mam plik tekstowy o strukturze tak:Parse plik tekstowy z XSLT

!ITEM_NAME 
Item value 
!ANOTHER_ITEM 
Its value 
... 

to możliwe, aby dostać się z XSLT plik podobny do:

<?xml version="1.0" encoding="UTF-8" ?> 
<document> 
    <ITEM_NAME>Item value</ITEM_NAME> 
    <ANOTHER_ITEM>Its value</ANOTHER_ITEM> 
    ... 
</document> 

EDIT

Przepraszam, że nie powiedziałem wcześniej jasno. Próbuję dokonać tej transformacji za pomocą silnika Visual Studio 2005 XSLT. Próbowałem obu dostarczonych rozwiązań i jestem pewien, że są poprawne. Ale program Visual Studio 2005 nie zna funkcji niezaprogramowanego tekstu.

+0

Nie jest to możliwe, ponieważ jedynym poprawnym wprowadzeniem do XSLT jest dobrze sformatowany Xml. –

+0

@ O.R.Mapper według tego pytania jest możliwe [link] (http://stackoverflow.com/questions/5675889/regular-text-file-to-xml-using-xslt) – sblandin

+0

Interesujące. Dzisiejszy wpis w "żarówce może * również * może być użyty do smażenia steku." lista ... dzięki za link :-) –

Odpowiedz

5

Jeśli można użyć XSLT 2.0 można użyć unparsed-text() ...

Text File (Nie należy korzystać z pliku tekstowego jako bezpośredni wkład w XSLT.)

!ITEM_NAME 
Item value 
!ANOTHER_ITEM 
Its value 
!TEST_BANG 
Here's a value with !bangs!!! 

XSLT 2.0 (Zastosuj ten XSLT do siebie (użyj arkusza stylów jako wejścia XML) Musisz również zmienić ścieżkę do pliku tekstowego. Może być również konieczna zmiana kodowania.)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="text-encoding" as="xs:string" select="'iso-8859-1'"/> 
    <xsl:param name="text-uri" as="xs:string" select="'file:///C:/Users/dhaley/Desktop/test.txt'"/> 

    <xsl:template name="text2xml"> 
     <xsl:variable name="text" select="unparsed-text($text-uri, $text-encoding)"/> 
     <xsl:analyze-string select="$text" regex="!(.*)\n(.*)"> 
      <xsl:matching-substring> 
       <xsl:element name="{normalize-space(regex-group(1))}"> 
        <xsl:value-of select="normalize-space(regex-group(2))"/> 
       </xsl:element> 
      </xsl:matching-substring> 
     </xsl:analyze-string> 
    </xsl:template> 

    <xsl:template match="/"> 
     <document> 
      <xsl:choose> 
       <xsl:when test="unparsed-text-available($text-uri, $text-encoding)"> 
        <xsl:call-template name="text2xml"/>         
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:variable name="error"> 
         <xsl:text>Error reading "</xsl:text> 
         <xsl:value-of select="$text-uri"/> 
         <xsl:text>" (encoding "</xsl:text> 
         <xsl:value-of select="$text-encoding"/> 
         <xsl:text>").</xsl:text> 
        </xsl:variable> 
        <xsl:message><xsl:value-of select="$error"/></xsl:message> 
        <xsl:value-of select="$error"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </document> 
    </xsl:template> 
</xsl:stylesheet> 

XML Output

<document> 
    <ITEM_NAME>Item value</ITEM_NAME> 
    <ANOTHER_ITEM>Its value</ANOTHER_ITEM> 
    <TEST_BANG>Here's a value with !bangs!!!</TEST_BANG> 
</document> 
+1

Czy zagnieżdżony ciąg analizujący jest niezbędny? Nie możesz po prostu użyć 'regex ="! (. *) \ N (. *) 'W zewnętrznym łańcuchu analizującym, a następnie wyodrębnić nazwę i wartość? –

+0

@MartinHonnen - Tak i miał coś takiego pierwotnie. dlaczego dodałem to z powrotem. Będę aktualizował.Dzięki! –

+1

Zaktualizował również dane wejściowe/wyjściowe xml, aby pokazać wartości z '!'. –

4

To XSLT 2.0 Transformacja:

<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= 
"replace(unparsed-text('file:///c:/temp/delete/text.txt'),'\r','')"/> 

<xsl:template match="/"> 
    <document> 
     <xsl:analyze-string select="$vText" regex="(!(.+?)\n([^\n]+))+"> 
     <xsl:matching-substring> 
     <xsl:element name="{regex-group(2)}"> 
       <xsl:sequence select="regex-group(3)"/> 
     </xsl:element> 
     </xsl:matching-substring> 
     <xsl:non-matching-substring><xsl:sequence select="."/></xsl:non-matching-substring> 
     </xsl:analyze-string> 
    </document> 
</xsl:template> 
</xsl:stylesheet> 

gdy appliedon każdy dokument XML (nie używany) i posiadające dostarczonego tekstu przebywających w pliku lokalnym C:\temp\delete\Text.txt:

!ITEM_NAME 
Item value 
!ANOTHER_ITEM 
Its value 
... 

produkuje Wanted, poprawny wynik:

<document> 
    <ITEM_NAME>Item value</ITEM_NAME> 
    <ANOTHER_ITEM>Its value</ANOTHER_ITEM> 
... 
</document> 

przetestować pełniej, kładziemy ten tekst w pliku:

As is text 
!ITEM_NAME 
Item value 
!ANOTHER_ITEM 
Its value 
As is text2 
!TEST_BANG 
Here's a value with !bangs!!! 
!TEST2_BANG 
!!!Here's a value with !more~ !bangs!!! 
As is text3 

Transformacja znowu produkuje poszukiwany, Prawidłowy wynik:

<document>As is text 
<ITEM_NAME>Item value</ITEM_NAME> 
<ANOTHER_ITEM>Its value</ANOTHER_ITEM> 
As is text2 
<TEST_BANG>Here's a value with !bangs!!!</TEST_BANG> 
<TEST2_BANG> !!!Here's a value with !more~ !bangs!!!</TEST2_BANG> 
As is text3 
</document> 
+0

Wielkie dzięki za wszystkie odpowiedzi ... Właśnie odkryłem, że Visual Studio 2005 (IDE Jestem zmuszony użyć) Parser XSLT nie zna funkcji niezapisanego tekstu. Przepraszamy za brak wystarczającego kontekstu. – sblandin