2009-08-27 12 views
1

属性を単一の要素にする必要があります。私を案内してください。シーケンス属性を必要な場所で単一要素に変換する方法は?

ここに私の入力と要件。

入力:

<book pagenum="01"> 
<title pagenum="01">Book title</title> 
<chapter pagenum="02"> 
<chaptertitle pagenum="02">CHAPTER TITLE</chaptertitle> 
<section pagenum="03"> 
<sectiontitle pagenum="03">SECTION TITLE</chaptertitle> 
<subsection pagenum="04"> 
<para pagenum="04">body content</para> 
<para pagenum="04">body content</para> 
<para pagenum="04">body content</para> 
<para pagenum="05">body content</para> 
<para pagenum="05">body content</para> 
<para pagenum="05">body content</para> 
<para pagenum="06">body content</para> 
<para pagenum="06">body content</para> 
</subsection></section></chapter></book> 

出力:XSLTスクリプトでこれを変換する方法

<book> 
<?docpage num="01"?><pagenum id="p01">01</pagenum> 
<booktitle>Book title</booktitle> 
<chapter> 
<?docpage num="02"?><pagenum id="p02">02</pagenum> 
<chaptertitle>CHAPTER TITLE</chaptertitle> 
<section> 
<?docpage num="03"?><pagenum id="p03">03</pagenum> 
<sectiontitle>SECTION TITLE</chaptertitle> 
<subsection> 
<?docpage num="04"?><pagenum id="p04">04</pagenum> 
<para>body content</para> 
<para>body content</para> 
<para>body content</para> 
<?docpage num="05"?><pagenum id="p05">05</pagenum> 
<para>body content</para> 
<para>body content</para> 
<para>body content</para> 
<?docpage num="06"?><pagenum id="p06">06</pagenum> 
<para>body content</para> 
<para>body content</para> 
</subsection></section></chapter></book> 

...?私を案内してください。

おかげで、これらの線に沿って マイケル

+0

次の時間正しく書式コードにコードの書式設定(ツールバー上の '0101'ボタン)を使用してください - それ以外の場合は、読み取り不能だとXMLのために、これは非常に重要です。 –

+0

申し訳ありませんパベル、私はあなたを得る!..!あなたは属性値を意味するのですか?もう一度来ることができます..? – Micheal

+0

あなたの質問(または回答)にコードがある場合、正しくフォーマットするには、各行を4つのスペースで開始する必要があります。エディタで、 "0101"と表示されているボタンは、現在の選択に対してそれを行います。これについては、書式設定を修正するために編集しました。ここにその前に見えた方法です:http://stackoverflow.com/posts/1339431/edit/16f34505-38ed-410c-bb26-5a84dc0ed2ab –

答えて

2

何か:

<!-- Identity transform - copy all elements as is by default --> 
<xsl:template match="node() | @*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
</xsl:template> 

<!-- Match any element for which @pagenum is different from preceding one. 
    Note that <para> is handled specially below. --> 
<xsl:template match="*[@pagenum != preceding::*[1]/@pagenum]"> 
    <xsl:copy> 
    <!-- Insert the PI and <pagenum> as first child --> 
    <xsl:call-template name="insert-pagenum"/> 
    <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
</xsl:template> 

<!-- Match <para> for which @pagenum is different from preceding one. --> 
<xsl:template match="para[@pagenum != preceding::*[1]/@pagenum]"> 
    <!-- Insert the PI and <pagenum> before the opening tag of <para> --> 
    <xsl:call-template name="insert-pagenum"/> 
    <xsl:copy> 
    <xsl:apply-templates select="node() | @*" /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template name="insert-pagenum"> 
    <xsl:processing-instruction name="docpage"> 
    <xsl:text>num=</xsl:text><xsl:value-of select="@pagenum"/> 
    </xsl:processing-instruction> 
    <pagenum id="p{@pagenum}"> 
    <xsl:value-of select="@pagenum"/> 
    </pagenum> 
</xsl:template> 
+0

ありがとうございましたPavel ..うまく動作します! :) – Micheal

+0

マイケルマークパベルの答えが受け入れられた(チェックマーク)は、あなたのために働いた場合。また彼upvote :) –

+0

情報のために、 "preceeding ::"これを行うのは非常に高価な方法です。ミュンヘンのアプローチ(「キー」付き)ははるかに迅速です。 –

2

だからあなただけの各々の第1のために@pagenumを書きたいですか?何かのように:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="pages" match="//@pagenum" use="." /> 

    <xsl:template match="@* | node()"> 
    <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy> 
    </xsl:template> 
    <xsl:template match="@pagenum"> 
    <xsl:if test="generate-id() = generate-id(key('pages', .))"> 
     <xsl:processing-instruction name="docpage">num=<xsl:value-of select="."/></xsl:processing-instruction> 
     <pagenum id="p{.}"><xsl:value-of select="."/></pagenum> 
    </xsl:if> 
    </xsl:template> 
    <xsl:template match="title"> 
    <booktitle><xsl:apply-templates select="@* | node()"/></booktitle> 
    </xsl:template> 
</xsl:stylesheet> 
+0

+1、それは方法的に優れた解決策です。そして、私はおそらくそれをより厳密にインデントするでしょう。 – Tomalak

+1

"generate-id()= generate-id(key( 'pages'、。))"という行は、 "私は最初ですか? –

+0

これは、常に生成された要素を@pagenumを持つ要素の子として配置します。サンプル出力を注意深く見てみると、これは ''では当てはまりません。そのためには、要素の前に生成された要素を配置しなければなりません。 –

関連する問題