2

XSLT を使用して XML ファイルを別の XML ファイルに変換しています。XML ファイルには次のような要素があります。

<Course>
      <ID>1001</ID>
      <Seats>10</Seats>
      <Description>Department: CS , Faculty: XYZ</Description>
</Course>

XSLT には、次のような新しい XML ファイルを生成する方法があります。

<Course>
      <ID>1001</ID>
      <Seats>10</Seats>
      <Department> CS </Department> 
      <Faculty> XYZ</Faculty>
</Course>

つまり、 Description要素を、基本的にコンマで区切られたコンテンツであるDepartmentFacilityという 2 つの異なる要素に分割したいと考えています。XMLspy を使用して XSLT を記述しました。

前もって感謝します。

4

1 に答える 1

2

以下は、Description 要素に固有のテンプレート内の恒等変換とトークン化文字列関数に基づく、考えられる XSLT2 ソリューションの 1 つです。

一般的な考え方は、最初に説明文字列を「,」で分割し、次に結果の各部分文字列を「:」で分割して、最後の部分のみを選択することです。

<?xml version="1.0"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Description">
        <xsl:variable name="tokens" select="fn:tokenize(text(),',')"/>
        <xsl:element name="Department"><xsl:value-of select="fn:normalize-space(fn:tokenize($tokens[1],':')[2])"/></xsl:element>
        <xsl:element name="Faculty"><xsl:value-of select="fn:normalize-space(fn:tokenize($tokens[2],':')[2])"/></xsl:element>
    </xsl:template>

</xsl:stylesheet>

先頭/末尾のスペースを削除するために、正規化スペース関数が最後のステップとして呼び出されます。これが必要ない場合は、そのビットを省略してください。

警告: ここでの前提は、説明テキストの形式が固定されていることです (つまり、学科と学部は常に同じ順序で存在します)。

上記の変換により、期待される結果が得られます。

<?xml version="1.0" encoding="UTF-8"?><Course>
      <ID>1001</ID>
      <Seats>10</Seats>
      <Department>CS</Department>
      <Faculty>XYZ</Faculty>
</Course>

一連のプレーン テキスト内に構造化された情報を格納することは、XML を最大限に活用することにはならないことに注意してください。XML はすべて構造に関するものですが、フォーマットはユーザーが制御できるものではないと思います。

コメントに基づく更新:

正規表現マッチングに基づく、より堅牢な代替ソリューションを以下に示します。この場合、Department、Faculty パターンに一致する Description 要素のみが書き換えられます。それ以外の場合は、元の Description 要素が渡されます。

<?xml version="1.0"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Description">
        <xsl:analyze-string select="." regex="\s*Department:\s*(.+)\s*,\s*Faculty:\s*(.+)\s*">
            <xsl:matching-substring>
                <xsl:element name="Department"><xsl:value-of select="regex-group(1)"/></xsl:element>
                <xsl:element name="Faculty"><xsl:value-of select="regex-group(2)"/></xsl:element>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:element name="Description"><xsl:copy/></xsl:element>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>

</xsl:stylesheet>

ここでの重要なアイデアは、予想されるパターンが見つかった場合にXSLT 正規表現xsl:analyze-stringを使用してテストし、その場合はそれぞれの値を取得することです。一致するものが見つからない場合は、Description 要素の元のコンテンツがコピーされます。

注: これをルート要素と統合することは、読者の演習として残されています (OP の例では Course 要素がどこに収まるかが示されていないため)。

于 2013-01-25T19:37:28.207 に答える