2016-10-18 4 views
0

の間で最初に来るのテスト:XSLT2 - ノードはこの構造を考えるとオプション

<body> 
    <h1>Main Title</h1> 
    <p class="sectiontitle>Title</p> 
    <p class="bodytext">some text</bodytext> 
    <ul>...</ul> 
    <p class="paragraphtitle>Subtitle</p> 
    <p class="bodytext">some text</bodytext> 
</body> 

またはparagraphtitleとsectiontitleが逆転している。この1:

<h1>Main Title</h1> 
    <p class="paragraphtitle>Title</p> 
    <p class="bodytext">some text</bodytext> 
    <ul>...</ul> 
    <p class="sectiontitle>Subtitle</p> 
    <p class="bodytext">some text</bodytext> 
</body> 

私は別に、このXML構造を転換していますXML(DITA)のフレーバーであり、このために、どのノードが最初に来るのかを知る必要があります。これは、ファイルの残りの部分を処理する方法を教えてくれるからです。
最初に何が起こったかを知るまで、ファイルを処理する方法は他にありません。
これらのタイトルの前にh1、h2、h3 ...要素があることは知っています。メインタイトルとクローズドボディータグの間には、<p class=bodytext>要素があります。それは非常にランダムです。

どのようなものが最初に来るのかを教えてください:セクションタイトルpまたはパラグラフタイトルp。

私は次のように選択に入れるいくつかのクレイジーな表現で試してみた:(まだ何かを微調整する必要がある)、ほとんどの場合に動作することを

body/p[@class='sectiontitle'][1]/preceding-sibling::p[@class!='paragraphtitle'][last()]/preceding-sibling::*[not(self::p[@class='sectiontitle' or @class='paragraphtitle']) and preceding-sibling::h1] 

または

body/p[@class='paragraphtitle'][1]/preceding-sibling::p[@class!='sectiontitle'][last()]/preceding-sibling::*[not(self::p[@class='sectiontitle' or @class='paragraphtitle']) and preceding-sibling::h1] 

が、私はそこに感じます可能性のリストの中で最初にどのノードが来るのかを簡単に伝える必要があります。

絶対位置を取得する方法はありますか?

if absposition(paragraphtitle[1]) < absposition(sectiontitle[1]) then 
+0

は、なぜあなたは最初に来るかを知る必要がありますか?ここで解決しようとしている**本当の**問題は何ですか? –

+0

私はファイルをどのように処理するかを知るためにファイルを識別しようとしています。私は2つの図形を知っています。まず、sectiontitle最初に、それに基づいてparagraphtitleを作成します。 – Flag

答えて

0

絶対位置を取得する方法はありますか?以下のように表すことができ、その後...

、最初sectiontitleparagraphtitleがある場合

:何か私はあなたの条件として修正再表示することができ信じて absposition(paragraphtitle[1]) < absposition(sectiontitle[1]) then

場合のように:

<xsl:choose> 
    <xsl:when test="/body/p[@class='sectiontitle'][1]/preceding-sibling::p[@class='paragraphtitle']">paragraph title is first</xsl:when> 
    <xsl:otherwise>section title is first</xsl:otherwise> 
</xsl:choose> 

これはXSLT 1.0と2.0の両方で機能します。すでに述べたように、XSLT 2.0で、あなたはテストが正確にあなたの元の文に合うようにモデル化することができます:

<xsl:when test="/body/p[@class='paragraphtitle'][1] &lt;&lt; /body/p[@class='sectiontitle'][1]">paragraph title is first</xsl:when> 

かを:

<xsl:when test="/body/p[@class='sectiontitle'][1] >> /body/p[@class='paragraphtitle'][1]">paragraph title is first</xsl:when> 
+0

それは私が予想したよりもはるかに簡単で、それはそのトリックです。ありがとうございました! – Flag

0

のようなものは、XSLT 2.0では、あなたは<<演算子を使用することができます:あなたが先行兄弟と、次の-兄弟以外には現実的な選択肢を持っていないしました1.0で

if (p[@class='paragraphtitle'] << p[@class='sectiontitle']) ... 

。しかし、あなたの候補式には、これらの2つのサンプルを区別する必要のないディテールが含まれているため(例えば、両方に存在するh1要素のテストなど)、詳細についてはアドバイスできません。そこに理由がある。

もう1つのオプション(ノードセット拡張が必要)は、興味のない要素をすべて除外してリストをフィルタリングし、<xsl:if test="p[1][self::sectiontitle]">を使用してフィルタリングされたリストをテストすることです。

これはなぜ実際に問題になるのでしょうか?おそらくあなたの本来の目的は要素を標準的な順序に並べ替えることです。この場合、ソート技術を検討する必要があります。

+0

あなたの答えはマイケルありがとうございます。私は少しの情報を追加しましたが、私は多くのファイルがあります。私はnode-before関数があなたが言及した<<演算子に関する情報を見つけようとしていることを発見しました。私はそれに行くつもりです。 – Flag

+0

'<< '演算子は' < < 'とエスケープしないと使えないことに注意してください。 –

+0

@Flag op:node-before関数は '<<'演算子のセマンティクスを指定する方法として存在します。この機能は、ユーザーアプリケーションには使用できません。 –

関連する問題