0

こんにちは、この質問はすべてこれに関連しています: xsl get element values from another node treeしかし、今回は動作する xslt があります。

現在、次のxmlに取り組んでいます。

 <record>
  <leader>01877nz  a2200433o  4500</leader>
  <controlfield tag="001">1</controlfield>
        ... (more controlfields tag 002 to 010)
  <datafield tag="013" ind1=" " ind2=" ">
   <subfield code="a">formerge</subfield>
  </datafield>
          ... (more datafield tags, datafield tags are from 011 to 999)
  <datafield tag="150" ind1=" " ind2=" ">
   <subfield code="a">Borneo</subfield>
  </datafield>
          ... (more datafield tags, datafield tags are from 011 to 999)
  <datafield tag="550" ind1=" " ind2=" ">
   <subfield code="w">g</subfield>
   <subfield code="a">South East Asia</subfield>
   <subfield code="c">c_7260</subfield>
  </datafield>
       ... (more datafield tags, datafield tags are from 011 to 999)
  </record>

       ... (more records)

  <record>
       ... (more records fields)
       ... (more records fields)
  </record>

  <record>
   <leader>02462nz  a2200553o  4500</leader>
   <controlfield tag="001">2</controlfield>
         ... (more controlfields tag 002 to 010)
   <datafield tag="013" ind1=" " ind2=" ">
    <subfield code="a">formerge</subfield>
   </datafield>
   <datafield tag="035" ind1=" " ind2=" ">
    <subfield code="a">c_7260</subfield>
   </datafield>
       ... (more datafield tags, datafield tags are from 011 to 999)
   <datafield tag="151" ind1=" " ind2=" ">
    <subfield code="a">South East Asia</subfield>
   </datafield>
       ... (more datafield tags, datafield tags are from 011 to 999)
  </record>

次の xslt があります。

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim"    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"    xmlns:dc="http://purl.org/dc/elements/1.1/"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="marc">
 <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
 <xsl:key name="term" match="//datafield[@tag='151'][subfield[@code='a']]" use="." />

 <xsl:template match="//datafield[@tag='151'][subfield[@code='a']]">
  <xsl:variable name="t550a" select="//datafield[@tag='550'][subfield[@code='a']]" />
  <xsl:for-each select="key('term','$550a')">
   <xsl:value-of select="//controlfield[@tag='001']" />
  </xsl:for-each>
 </xsl:template>

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

</xsl:stylesheet>

これで、キー(用語)を介して151個すべてのインデックスを作成しました。変数「t550a」も作成しました。keys 関数を使用して、550a タグ (datafield tag="550" subfield code="a") を term key と照合します。そして、そのキーのコントロールフィールドタグ 001 の値を取得します。また、xml のすべてのノード、つまり「xsl:copy」を取得したかったのです。私が持っている xslt では、datafield タグ 151 が削除されているようです。

私は550フィールドに次のものを入れたかった:

        ... (other fields omitted)
<datafield tag="550" ind1=" " ind2=" ">
 <subfield code="w">g</subfield>
 <subfield code="a">South East Asia</subfield>
 <subfield code="c">c_7260</subfield>
 <subfield code="0">2</subfield>
</datafield>
          ... (other fields omitted)

<datafield tag="550" ind1=" " ind2=" ">
 <subfield code="w">h</subfield>
 <subfield code="a">Borneo</subfield>
 <subfield code="c">c_1017</subfield>
 <subfield code="0">1</subfield>
</datafield>

したがって、東南アジアの 550 サブフィールドには、東南アジアの 151 サブフィールドの制御フィールド 001 に基づいて、値 2 を持つ追加のサブフィールド 0 があります。また、ボルネオの 550 サブフィールドには、ボルネオの 151 サブフィールドの制御フィールド 001 に基づいて、値が 1 のサブフィールド 0 が追加されます。

誰かがこれを正しく行うように導くことができますか? ありがとう!

4

2 に答える 2

1

テンプレートが間違った要素に一致していると思います。「550」フィールドに子ノードを追加する場合は、それに一致するテンプレートが必要です。

<xsl:template match="datafield[@tag='550'][subfield[@code='a']]">

現時点ではキーも空白ノードを使用するため、キーをこれに合わせてわずかに調整します (ただし、使用している場合は削除される可能性があります)。xsl:strip-space

 <xsl:key name="term" match="datafield[@tag='151']" use="subfield[@code='a']" />

次の問題は、tt50a変数の定義にあります。現時点では、ドキュメント内のどこからでも最初に一致する要素が取得されるため、ここでは相対式を使用する必要があります。代わりにこれを行う必要があります (550ノードに配置されているため、これは機能します) 。

<xsl:variable name="t550a" select="subfield[@code='a']" />

ただし、実際にはこの変数を使用していないようです。キーの現在の使用はkey('term','$550a')、変数ではなく文字列リテラルを使用しています。おそらくこれを行うつもりです:

<xsl:for-each select="key('term',$t550a)">

そして最後に、xsl:for-eachあなたがしている場所の中で//controlfield[@tag='001']、これはドキュメントの最初のものを選択しcontrolfieldます。現在のもののみを選択したいと思いますrecordrecordcurrent の親であるため、これdatafieldを行うことができます:

<xsl:value-of select="../controlfield[@tag='001']" />

このXSLTを試してください

<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"  xmlns:dc="http://purl.org/dc/elements/1.1/"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="rdf dc marc">
 <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
 <xsl:key name="term" match="datafield[@tag='151']" use="subfield[@code='a']" />

 <xsl:template match="datafield[@tag='550'][subfield[@code='a']]">
   <xsl:variable name="t550a" select="subfield[@code='a']" />
   <xsl:copy>
     <xsl:apply-templates select="@*|node()"/>
     <xsl:for-each select="key('term',$t550a)">
       <subfield code="0">
         <xsl:value-of select="../controlfield[@tag='001']" />
       </subfield>
      </xsl:for-each>
    </xsl:copy>
 </xsl:template>

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

550入力XMLにはノードが1つしかないため、質問に表示されている出力が正確に得られるわけではありません。

于 2015-09-09T12:53:53.753 に答える
1

私が持っている xslt では、datafield タグ 151 が削除されているようです。

はい、それは正しいです。なぜなら、それはあなたがそれをするように指示したからです:

 <xsl:template match="//datafield[@tag='151'][subfield[@code='a']]">
  <xsl:variable name="t550a" select="//datafield[@tag='550'][subfield[@code='a']]" />
  <xsl:for-each select="key('term','$550a')">
   <xsl:value-of select="//controlfield[@tag='001']" />
  </xsl:for-each>
 </xsl:template>

これは、次のことを意味します:datafieldが一致すると、値を持つすべての項を$550a調べて、反復ごとに (ルートから!) すべての制御フィールド値を選択します。のように、現在のノードから制御フィールドを取得したいと思い.//controlfield....ます。

ただし、ここでは要素を作成していません。それが必要な場合は、おそらくそれを追加する必要があります。すなわち:

 <xsl:template match="//datafield[@tag='151'][subfield[@code='a']]">
  <xsl:variable name="t550a" select="//datafield[@tag='550'][subfield[@code='a']]" />
  <xsl:copy>
    <xsl:for-each select="key('term','$550a')">
      <xsl:value-of select="//controlfield[@tag='001']" />
    </xsl:for-each>
   </xsl:copy>
 </xsl:template>

をコピーしdatafieldます。

于 2015-09-09T09:39:25.373 に答える