大家好,这个问题与此有关:xsl get element values from another node tree但这次我有一个工作的xslt。
我目前正在处理以下xml:
/Users/xxx/Documents/eclipse/Eclipse.app/Contents/MacOS/birimler/imageLogo.png
我有以下xslt:
<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>
有了这个,我创建了一个通过键(term)的所有151的索引。我还创建了一个变量&#39; t550a&#39;。通过键功能,我将550a标签(datafield标签=&#34; 550&#34;子字段代码=&#34; a&#34;)与term键匹配。然后获取该键的controlfield标签001的值。我还想得到我的xml的所有节点,因此&#34; xsl:copy&#34;。使用xslt,似乎正在删除数据字段标记151。
我想在550字段中获得以下内容:
<?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>
因此,东南亚的550子场将具有值为2的额外子场0,其基于东南亚的151个子场的控制域001。此外,婆罗洲还有550个子场,将有另外一个值为1的子域0,它基于一个婆罗洲151子场的控制域001。
有人可以引导我正确地做这件事。谢谢!
答案 0 :(得分: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....
?
但你不是在这里创造任何元素。如果你想要,你应该添加它。即:
<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
。
答案 1 :(得分:1)
我认为您的模板与错误的元素匹配。如果您要将子节点添加到&#34; 550&#34;字段,你应该有一个匹配
的模板<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
。我想你只想选择当前record
中的那个。由于record
是当前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
节点。