XSLT には、remove()
シーケンス用の関数があります。シーケンスと位置を指定すると、シーケンスから指定された位置の項目を引いたものを返します。
問題は、実際の XSLT ファイルでこの関数を使用するにはどうすればよいかということです。
コンテキストを完全に欠いた関数仕様の単なる逆流ではない例についての言及を見つけた唯一の場所は、http: //books.google.com/books?id=W6SpffnfEPoC&pg=PA776&lpg=PA776&dq=xslt+です。 %22remove+function%22&source=bl&ots=DQQrnXF_nB&sig=nrJtpEvYjBaZU0K8iAtdPTGUIbI&hl=en&sa=X&ei=QOq8T7aPDOyI6AHh-JBP&ved=0CEQQ6AEwAQ#v=onepage&q=xslt%20%22remove%20function%22&f=false
残念ながら、スタイルシートの例は 777 ページと 778 ページにありますが、もちろん含まれていません。そして、私はその本を所有していません。
remove()
では、実際のスタイルシートで XSLT 関数を使用した例はありますか?
編集:もう少し具体的な例を挙げましょう。
XSLT にシーケンスがあります。このシーケンスは、テキスト ファイルのすべての行で構成されています。
<xsl:variable name="lines" select="tokenize(unparsed-text($filePath), '\r?\n')" />
これらの行はすべてレコードです...1 つを除いて、レコード数がわかります。そのため、その行を見つけるための次のコードがあります。
<xsl:variable name="recordCount">
<xsl:for-each select="$lines[position()]">
<xsl:variable name="i" select="position()" />
<xsl:analyze-string select="$lines[$i]" regex="RECORD COUNT = \d+">
<xsl:matching-substring>
<xsl:value-of select="replace($lines[$i], '[^0-9]', '')" />
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</xsl:variable>
行をループして実際のすべてのレコードを取得する前に上記を実行するため、ここでの目標は、「RECORD COUNT」行$lines
を見つけたときにシーケンスから削除することです。そうすれば、レコードを取得してループするときに、「これは実際にはレコードではなく、実際には RECORD COUNT 行ですか? "
編集 (2): Martin Honnen の回答に基づいて、私の最終的な XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!-- I want to produce an XML document. -->
<xsl:output method="xml" indent="yes" />
<!-- Path to input text file. -->
<xsl:param name="filePath" select="TestFile.txt" />
<!-- Regex in replace() removes leading and trailing blank space. -->
<xsl:variable name="text" select="replace(unparsed-text($filePath), '(^[\r\n]*\s*[\r\n]+)|([\r\n]+\s*[\r\n]*$)', '')" />
<!-- Regex in tokenize() sets the delimiter to be any blank space between record lines. -->
<!-- This effectively removes any blank lines. -->
<xsl:variable name="lines" select="tokenize($text, '[\r\n]+\s*[\r\n]*')" />
<!-- This finds the "RECORD COUNT = ?" line. -->
<xsl:variable name="recordCountIndex"
select="for $pos in 1 to count($lines) return $pos[matches($lines[$pos], 'RECORD COUNT = \d+')]" />
<!-- Regex in replace() strips everything that's not a number, leaving only the numeric count. -->
<!-- Example: "RECORD COUNT = 25" -> "25" -->
<xsl:variable name="recordCount" select="replace($lines[$recordCountIndex], '[^0-9]', '')" />
<xsl:template name="main">
<root>
<recordCount>
<!-- The record count value being inserted. -->
<xsl:value-of select="$recordCount" />
</recordCount>
<records>
<!-- Iterate over the $lines minus the line containing the record count. -->
<xsl:for-each select="remove($lines, $recordCountIndex)">
<!-- Items in each record, split by blank space. -->
<!-- Example: "a b c" -> "[a, b, c]" -->
<xsl:variable name="record" select="tokenize(., ' ')[position()]" />
<record>
<aThing>
<xsl:value-of select="$record[1]" />
</aThing>
<aDifferentThing>
<xsl:value-of select="$record[2]" />
</aDifferentThing>
<someStuff>
<xsl:value-of select="$record[3]" />
</someStuff>
</record>
</xsl:for-each>
</records>
</root>
</xsl:template>
</xsl:stylesheet>