0

私は以下のようなxmlドキュメントを持っています、

<chapter xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="chapter1">
<title>First chapter</title>
<section xml:id="section1">
                <imageobject>
                    <image fileref="images/image1.jpg"/>
                </imageobject>
                <imageobject>
                    <image fileref="images/image2.jpg"/>
                </imageobject>
</section>
    <section xml:id="section2" xml:base="../other/section1.xml">  
                    <imageobject>
                        <image fileref="images/image1.jpg"/>
                    </imageobject>
                    <imageobject>
                        <image fileref="images/image2.jpg"/>
                    </imageobject>

<section xml:id="section3" xml:base="../some-other/more/section3.xml">
                    <imageobject>
                        <image fileref="images/image1.jpg"/>
                    </imageobject>
    </section>
    </section>
    <section xml:id="section4" xml:base="../some-other/section4.xml">
                    <imageobject>
                        <image fileref="images/image2.jpg"/>
                    </imageobject>
    </section>
 </chapter>

同じ画像名が異なるセクションで繰り返されているため、Javaクラスを使用して最初のセクション以外のすべての画像名の名前を変更しています。次に、名前が変更された画像名のリストを生成できます。

次に、これらの変更を上記のxmlファイルにも反映させたいと思います。たとえば、セクション2で「image1.jpg」の名前を「aaa.jpg」に変更する場合、名前を変更した新しい画像名で新しいxmlを生成することにより、その変更を最初のxmlに反映する必要があります。

そのために、XSLT 1.0を使用するAntスクリプトを使用しており、最初のxmlと名前を変更した画像リストを入力として取得し、新しいfileref値を使用して新しいxmlドキュメントを生成します。そのXSLTを作成し、Antスクリプトで使用するにはどうすればよいですか。

これが私の新しい名前変更された画像リストです。

<Imagedata>
  <section>
    <sectionID>section2</sectionID>
    <relativepath>images/aaa.jpg</relativepath>
    <relativepath>images/bbb.jpg</relativepath>
  </section>
  <section>
    <sectionID>section3</sectionID>
    <relativepath>images/ccc.jpg</relativepath>
  </section>
   <section>
    <sectionID>section4</sectionID>
    <relativepath>images/ddd.jpg</relativepath>
  </section>
</Imagedata>

そして、私の新しい最終的なxmlは、次のようなものになります。

<chapter xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="chapter1">
    <title>First chapter</title>
    <section xml:id="section1">
                    <imageobject>
                        <image fileref="images/image1.jpg"/>
                    </imageobject>
                    <imageobject>
                        <image fileref="images/image2.jpg"/>
                    </imageobject>
    </section>
        <section xml:id="section2" xml:base="../other/section1.xml">  
                        <imageobject>
                            <image fileref="images/aaa.jpg"/>
                        </imageobject>
                        <imageobject>
                            <image fileref="images/bbb.jpg"/>
                        </imageobject>

    <section xml:id="section3" xml:base="../some-other/more/section3.xml">
                        <imageobject>
                            <image fileref="images/ccc.jpg"/>
                        </imageobject>
        </section>
        </section>
        <section xml:id="section4" xml:base="../some-other/section4.xml">
                        <imageobject>
                            <image fileref="images/ddd.jpg"/>
                        </imageobject>
        </section>
     </chapter>

ありがとうございました..!!

4

1 に答える 1

1

簡単なデモンストレーションのために、Imagedataドキュメントを以下のスタイルシートショー内の変数に入れました。実際の使用では、次のように、画像データドキュメントのURIであるパラメータを渡します...

<xsl:param name="ImageDataURI" />
<xsl:variable name="ImageData" select="document($ImageDataURI)" />

それはさておき、このXSLT1.0スタイルシート...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes"/>

<xsl:variable name="ImageData">
<Imagedata>
  <section>
    <sectionID>section2</sectionID>
    <relativepath>images/aaa.jpg</relativepath>
    <relativepath>images/bbb.jpg</relativepath>
  </section>
  <section>
    <sectionID>section3</sectionID>
    <relativepath>images/ccc.jpg</relativepath>
  </section>
   <section>
    <sectionID>section4</sectionID>
    <relativepath>images/ddd.jpg</relativepath>
  </section>
</Imagedata>
</xsl:variable>

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

<xsl:template match="image/@fileref">
  <xsl:attribute name="fileref">
    <xsl:value-of select="
    (msxsl:node-set($ImageData)/Imagedata/section/
    sectionID[.=current()/../../../self::section/@xml:id]/
    following-sibling::relativepath[
     count( current()/../../preceding-sibling::imageobject) + 1
      ] | .)[1]"/>
  </xsl:attribute>  
</xsl:template>

</xsl:stylesheet>

...提供された入力ドキュメントを期待される出力ドキュメントに変換します。

説明

最後のテンプレートの式の値を検討してください。一致したfileref属性から始めて、セクションに移動してそのIDを取得するまで上に移動します。これは次の式で与えられます...

current()/../../../self::section/@xml:id

次に、ルックアップデータを取得し、sectionIDを見つけます。これは式によって与えられます...

msxsl:node-set($ImageData)/Imagedata/section/sectionID

これらのセクションをセクション名でクロスリンクする必要があります。これを実現するには、その値がフォーカスアイテムのセクション値でなければならないという述語をsectionIDに適用します。述語はここにあります...

[.=current()/../../../self::section/@xml:id]

これで、正しいルックアップセクションが見つかりました。ドキュメントセクション内のフォーカスアイテムの現在の位置によって、それにインデックスを付ける必要があります。前の兄弟を数え、次のように1つ追加することで、位置を計算します...

count( current()/../../preceding-sibling::imageobject) + 1

したがって、ルックアップ置換ノードが存在する場合は、次のようになります。

msxsl:node-set($ImageData)/Imagedata/section/
sectionID[.=current()/../../../self::section/@xml:id]/
following-sibling::relativepath[
 count( current()/../../preceding-sibling::imageobject) + 1

交換が必要な場合はこれで問題ありませんが、対応するルックアップがない場合があります。この場合、属性は元の値を保持する必要があります。これは、フォームの表現によって実現されます...

( $something | .)[1]

$ somethingが存在しない場合(つまり、値が空のシーケンスである場合)、上記の式は単にフォーカスアイテムを返します。存在する場合は、$somethingの最初のアイテムまたはフォーカスアイテムのいずれかが返されます。通常、ユニオン演算子は、ドキュメントの順序で重複排除と並べ替えの2つのシーケンスを連結します。ただし、2つのオペランドは異なるドキュメントからのものであるため、ソートや重複排除は行われません。したがって、式は、置換ノードが存在する場合はそれを返し、存在しない場合はフォーカスアイテムを返します。

于 2012-08-03T13:37:44.730 に答える