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,似乎正在删除数据字段标签 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 子字段将具有附加的子字段 0,其值为 2,该子字段基于 151 子字段 a 的东南亚的控制字段 001。此外,婆罗洲的 550 个子字段将具有附加的子字段 0,其值为 1,它基于婆罗洲 151 个子字段的控制字段 001。

有人可以引导我正确地做到这一点。谢谢!

4

2 回答 2

1

使用我拥有的 xslt,似乎正在删除数据字段标签 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....

但是您没有在这里创建任何元素。如果你想要那个,你可能应该添加它。IE:

 <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 回答
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文档中的第一个。我想你只想选择 current 中的那个record。作为recordcurrent 的父母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>

这不会准确给出您在问题中显示的输出,因为您的输入 XML 只有一个550节点。

于 2015-09-09T12:53:53.753 回答