2010-08-09 79 views
2

這已經是一個非常基本的問題,但我真的很困難的解決方案。從下面的XML,我想只提取第一個實例,當我對tag="099"匹配,並在marc:datafield節點code="a"屬性和marc:subfield節點,分別在XSL中,如何根據多個屬性選擇一個值?

<?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:datafield tag="079" ind1=" " ind2=" "> 
     <marc:subfield code="a">79927839</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="099" ind1=" " ind2=" "> 
     <marc:subfield code="a">940002</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="099" ind1=" " ind2=" "> 
     <marc:subfield code="a">940002*</marc:subfield> 
    </marc:datafield> 
    <marc:datafield tag="099" ind1=" " ind2=" "> 
     <marc:subfield code="a">940002**</marc:subfield> 
...   

所以,我試圖檢索第一個「940002」。使用下面的代碼:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" 
version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" 
xmlns:marc="http://www.loc.gov/MARC21/slim"> 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
<xsl:template match="/"> 
    <record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/"> 
     <!--identifier--> 
     <xsl:if test="/marc:collection/marc:record/marc:datafield/@tag='099'"> 
      <xsl:element name="dc:identifier"> 
       <xsl:if test="position()=1"> 
        <xsl:value-of select="/marc:collection/marc:record/marc:datafield/marc:subfield/@code='a'"/> 
       </xsl:if> 
      </xsl:element> 
     </xsl:if> 
... 

然而,就是我得到的是:

<?xml version="1.0" encoding="UTF-8"?> 
<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:dcterms="http://purl.org/dc/terms/" 
    xmlns:marc="http://www.loc.gov/MARC21/slim"> 
    <dc:identifier>true</dc:identifier> 
    ... 

代替所需的:

 <?xml version="1.0" encoding="UTF-8"?> 
<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:dcterms="http://purl.org/dc/terms/" 
    xmlns:marc="http://www.loc.gov/MARC21/slim"> 
    <dc:identifier>940002</dc:identifier> 
    ... 

我猜它一定是一個Xpath的問題,但...任何線索將不勝感激。

感謝

+0

問得好(+1)。查看我的答案,獲取簡單的單線XPath表達式。 :) – 2010-08-09 20:26:39

回答

2

使用

/marc:collection/marc:record/marc:datafield 
        [@tag='099']/marc:subfield[@code='a'][1]/text() 
+0

+1「是唯一正確的解決方案。 – 2010-08-09 21:24:50

2

更改此

<xsl:value-of select="/marc:collection/marc:record/marc:datafield/marc:subfield/@code='a'"/> 

<xsl:value-of select="/marc:collection/marc:record/marc:datafield/marc:subfield[@code='a']/text()"/> 

你的價值是選擇@code是否等於給'a'不是選擇marc:subfield其中@code='a'

+0

哇,這似乎是更符合正確的線條,但不是隻選擇當它上面的節點匹配'「'。它給了我一個巨大的連接字符串,每個'marc:subfield'都帶有一個'@ code ='a''。 – LOlliffe 2010-08-09 20:00:28

+1

嘗試將'marc:subfield [@ code ='a']'更改爲'marc:subfield [@ code ='a'] [1]''。 – 2010-08-09 20:07:28

+1

和@LOlliffe:這不符合'marc:datafield [@ tag ='099']'條件。見Dimitre的正確答案。 – 2010-08-09 21:17:36

1

明白了!在另一個選擇中添加了竅門。非常感謝你的幫助!

<xsl:for-each select="/marc:collection/marc:record/marc:datafield[@tag='099']"> 
    <xsl:element name="dc:identifier">` 
     <xsl:if test="position()=1"> 
      <xsl:value-of select="marc:subfield[@code='a']/text()"/> 
     </xsl:if> 
    </xsl:element> 
</xsl:for-each> 
+0

你不需要'xsl:for-each'並測試'position()'。這應該使用一個XPath表達式作爲Dimitre的答案來完成。你也不需要'xsl:element':如果你事先知道元素的名字,你應該輸出爲一個文字結果元素,例如:'<! - content - >< dc:標識符>' – 2010-08-09 21:20:47