1

INIからXMLへのある種の変換を行うことを検討しています。INI構文は単純です。私はsed/awk / grepを探していません。これは、実際にはXMLツールで実行する必要があります。

これは通常のXSLで実行できますか?Xflatについて聞いたことがありますが、Cでコンパイルされたツールからそれを行うことはできますか?xsltprocやxmlstarletなど。

一般的なINI構文は次のようになります...

[section]
option = values

これはこのようなxmlになります...

<section>
<option>values</option>
</section>

どんな助けでも大歓迎です。

4

3 に答える 3

4

これは通常のXSLで実行できますか?

はい。XSLT2.0は、テキストを処理するためにXSLT1.0よりも多くの機能を提供します。非常に複雑なテキスト処理がXSLTに実装されており、JSONやXPathなどの特定の文法のパーサーを構築するために使用される一般的なLR(1)パーサーが含まれています。

特に、正規表現、、および)を使用できる関数や命令などunparsed-text()、さまざまな文字列関数について学習します。matches()tokenize()replace()<xsl:analyze-string>

XSLT 1.0には文字列関数(XPath 1.0で提供される)もありますが、正規表現の機能/関数がなく、XSLT2.0関数などはありませんunparsed-text()。最も有用なXPath1.0文字列関数には、、、、、、、、、substring()特に関数がsubstring-before()あります。substring-after()starts-with()string-length()concat()translate()

Mads Hansenが回答で説明したように、DTD内のエンティティを使用してファイルを「読み取る」ことができます。もう1つの方法は、変換を開始するプログラムでファイルを読み取り、ファイルの内容を文字列パラメーターとして変換に渡すことです。

更新:OPが特定のデータを提供するようになったため、完全なソリューションが可能になります。

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

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

 <xsl:variable name="vLines" as="xs:string*" select=
   "tokenize($vText, '&#xD;?&#xA;')[.]"/>

 <xsl:variable name="vLineCnt" select="count($vLines)"/>

 <xsl:variable name="vSectLinesInds" as="xs:integer*" select=
  "for $i in 1 to $vLineCnt
     return
       if(starts-with(normalize-space($vLines[$i]), '['))
         then $i
         else ()
  "/>

 <xsl:variable name="vSectCnt" select="count($vSectLinesInds)"/>

 <xsl:template match="/">
  <xsl:for-each select="$vSectLinesInds">
    <xsl:variable name="vPos" select="position()"/>
    <xsl:variable name="vInd" as="xs:integer" select="."/>

     <xsl:variable name="vthisLine" as="xs:string"
          select="$vLines[$vInd]"/>

    <xsl:variable name="vNextSectInd" select=
     "if($vPos eq $vSectCnt)
        then
          $vLineCnt +1
        else
          $vSectLinesInds[$vPos +1]
     "/>

   <xsl:variable name="vInnerLines" select=
   "$vLines
       [position() gt current()
      and
        position() lt $vNextSectInd
       ]

   "/>

   <xsl:variable name="vName" select=
    "tokenize($vthisLine, '\[|\]')[2]"/>

   <xsl:element name="{$vName}">
    <xsl:for-each select="$vInnerLines">
      <xsl:variable name="vInnerParts" select=
      "tokenize(., '[ ]*=[ ]*')"/>

      <xsl:element name="{$vInnerParts[1]}">
        <xsl:value-of select="$vInnerParts[2]"/>
      </xsl:element>
    </xsl:for-each>
  </xsl:element>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

この変換が任意のXMLドキュメント(使用されていない)に適用され、のファイルに C:\temp\delete\test.ini 次の内容が含まれている場合:

[section1]
option1 = values1
option2 = values2
option3 = values3
option4 = values4
option5 = values5

[section2]
option1 = values1
option2 = values2
option3 = values3
option4 = values4
option5 = values5

[section3]
option1 = values1
option2 = values2
option3 = values3
option4 = values4
option5 = values5

必要な正しい結果が生成されます:

<section1>
   <option1>values1</option1>
   <option2>values2</option2>
   <option3>values3</option3>
   <option4>values4</option4>
   <option5>values5</option5>
</section1>
<section2>
   <option1>values1</option1>
   <option2>values2</option2>
   <option3>values3</option3>
   <option4>values4</option4>
   <option5>values5</option5>
</section2>
<section3>
   <option1>values1</option1>
   <option2>values2</option2>
   <option3>values3</option3>
   <option4>values4</option4>
   <option5>values5</option5>
</section3>
于 2011-12-08T13:18:57.447 に答える
2

はい、XSLTでプレーンテキストファイルを解析できます

それがあなたのオプションであるならば、XSLT2.0でそうすることはおそらくより簡単でしょう。

XSLT 2.0では、unparsed-text()関数を使用してファイルを読み取り、tokenize()を使用してファイルを行に分割できます。

<xsl:for-each select="tokenize(unparsed-text($in), '\r?\n')">
 ...
</xsl:for-each>

XSLT 1.0の場合:外部エンティティでテキストファイルを参照することにより、XMLファイルに組み込むことで多くのフラットテキストファイルを読み取ることができます(XML解析エラーの原因となる文字/パターンが含まれていない場合)。ファイルのテキストは、解析時にXMLファイルに含まれます。

<!DOCTYPE foo [
<!ENTITY bar SYSTEM "bar.txt">
]>
<foo>
&bar;
</foo>
于 2011-12-08T13:13:22.370 に答える
1

XSLT 2.0プロセッサを使用できる場合は、unparsed-text()フラットファイルをインポートできる機能があります。

ファイルがインポートされると、XPath 2.0にデータを処理するための従来の文字列ツール(正規表現、変換...)があります。http ://www.w3.org/TR/xpath-functions/#string-functionsを参照してください。

于 2011-12-08T10:54:38.383 に答える