我有成千上万的MarcXML记录,我需要从每条记录中选择和连接特定的字符串。不幸的是,我似乎只能让我的XSLT表从文件中每个MarcXML记录的第一条记录中获取相同的字符串。
我所拥有的MarcXML记录是这样的:
<?xml version="1.0" encoding="UTF-8" ?>
<marc:collection xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
<marc:record>
<marc:leader>01195cam a2200301 a 4500</marc:leader>
<marc:datafield tag="100" ind1="1" ind2="">
<marc:subfield code="a">Bache, Franklin,</marc:subfield>
<marc:subfield code="d">1792-1864.</marc:subfield>
</marc:datafield>
<marc:datafield tag="245" ind1="1" ind2="3">
<marc:subfield code="a">An obituary notice of Thomas T. Hewson, M. D. :</marc:subfield>
<marc:subfield code="h">[electronic resource]</marc:subfield>
<marc:subfield code="b">late president of the Philadelphia College of Physicians
</marc:subfield>
<marc:subfield code="c">by Franklin Bache ; read before the college, November 6, 1849 ; and published by its direction.</marc:subfield>
</marc:datafield>
<marc:datafield tag="260" ind1="" ind2="">
<marc:subfield code="a">Philadelphia :</marc:subfield>
<marc:subfield code="b">Geddes,</marc:subfield>
<marc:subfield code="c">1850.</marc:subfield>
</marc:datafield>
</marc:record>
<marc:record>
<marc:leader>01429cam a2200325 a 4500</marc:leader>
</marc:datafield>
<marc:datafield tag="110" ind1="2" ind2="">
<marc:subfield code="a">American Public Health Association.</marc:subfield>
<marc:subfield code="b">Committee on the Prevention of Venereal Diseases.</marc:subfield>
</marc:datafield>
<marc:datafield tag="245" ind1="1" ind2="0">
<marc:subfield code="a">Report of the Committee on the Prevention of Venereal Diseases :</marc:subfield>
<marc:subfield code="h">[electronic resource]</marc:subfield>
<marc:subfield code="b">presented at the eighth annual meeting of the American Public Health Association, New Orleans, La., Nov. 7-10, 1880.</marc:subfield>
</marc:datafield>
<marc:datafield tag="260" ind1="" ind2="">
<marc:subfield code="a">Boston :</marc:subfield>
<marc:subfield code="b">Franklin,</marc:subfield>
<marc:subfield code="c">1881.</marc:subfield>
</marc:datafield>
</marc: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="text" encoding="UTF-8" indent="no" />
- <xsl:template match="marc:collection">
- <xsl:for-each select="marc:record">
- <xsl:choose>
- <xsl:when test="contains(//marc:leader, 'cam')">
<xsl:call-template name="Title" />
<xsl:call-template name="Date" />
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
- <xsl:template name="Title">
<xsl:variable name="short" select="//marc:datafield[@tag=245]/marc:subfield[@code='a']" />
<xsl:value-of select="substring($short,1,20)" />
</xsl:template>
- <xsl:template name="Date">
<xsl:variable name="dd" select="//marc:datafield[@tag=260]/marc:subfield[@code='c']" />
<xsl:value-of select="substring($dd,1,4)" />
</xsl:template>
</xsl:stylesheet>
我希望输出类似于:
An obituary notice of1850
Report of the Committ1881
但我获得了第一个字符串的两倍。
我试过不使用<xsl:for-each>
,但结果是一样的。我可以解析每条记录的唯一方法是使用模板,但这不允许我选择特定的字符串。
任何人都可以帮助我吗?
答案 0 :(得分:2)
您遇到的问题是背景。在XPath的开头不需要使用//
。那是查询整个文档。在XSLT 1.0中,您只获得第一个结果。这就是你第二次看到第一根弦的原因。
这是样式表的更新版本。我删除了//
并更改了“标题”substring()
(以获取示例中的输出)。我还添加了换行符(

)。
更新了XSLT 1.0
<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="text" encoding="UTF-8" indent="no"/>
<xsl:template match="marc:collection">
<xsl:for-each select="marc:record">
<xsl:choose>
<xsl:when test="contains(marc:leader, 'cam')">
<xsl:call-template name="Title"/>
<xsl:call-template name="Date"/>
<xsl:text>
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template name="Title">
<xsl:variable name="short" select="marc:datafield[@tag=245]/marc:subfield[@code='a']"/>
<xsl:value-of select="substring($short,1,21)"/>
</xsl:template>
<xsl:template name="Date">
<xsl:variable name="dd" select="marc:datafield[@tag=260]/marc:subfield[@code='c']"/>
<xsl:value-of select="substring($dd,1,4)"/>
</xsl:template>
</xsl:stylesheet>
你可以摆脱额外的模板。我就是这样做的:
XSLT 1.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:marc="http://www.loc.gov/MARC21/slim"
exclude-result-prefixes="marc">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:apply-templates select="marc:record[contains(marc:leader, 'cam')]"/>
</xsl:template>
<xsl:template match="marc:record">
<xsl:value-of select="substring(marc:datafield[@tag=245]/marc:subfield[@code='a'],1,21)"/>
<xsl:value-of select="substring(marc:datafield[@tag=260]/marc:subfield[@code='c'],1,4)"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
这两个都会给你以下输出:
An obituary notice of1850
Report of the Committ1881