2012-11-13 117 views
4

我在寫一個xslt樣式表,將MARC-xml記錄轉換爲FGDC-xml元數據。很多MARC字段在最後(句號,冒號,逗號等)都有多餘的標點符號,我想刪除它們。儘管如此,我不想刪除全部標點符號。我的想法是編寫一個如果聲明和測試如果字段結束與指定的字符,然後將其刪除,但我不知道:1)如果這是一個好方法,2)如何指定該模板處理。xslt刪除結尾標點符號

編輯我的XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:marc="http://www.loc.gov/MARC21/slim" > 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

<xsl:template match="/"> 
<xsl:for-each select="marc:collection/marc:record"> 
    <xsl:result-document method="xml" href="banana_{marc:controlfield[@tag=001]}.xml"> 
    <metadata> 
     <xsl:apply-templates select="self::marc:record"/> 
    </metadata> 
    </xsl:result-document> 
</xsl:for-each> 
</xsl:template> 

<xsl:template match="marc:record"> 
    <pubinfo> 
    <pubplace><xsl:value-of select="marc:datafield[@tag=260]/marc:subfield[@code='a']"/></pubplace> 
    <publish><xsl:value-of select="marc:datafield[@tag=260]/marc:subfield[@code='b']" /></publish> 
    </pubinfo> 
</xsl:template> 

</xsl:stylesheet> 

這裏是我的xml文檔(或至少它的代表性部分):

<?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>01502cfm a2200313 a 4500</marc:leader> 
    <marc:controlfield tag="001">7943586</marc:controlfield> 
    <marc:datafield tag="260" ind1=" " ind2=" "> 
     <marc:subfield code="a">[S.l. :</marc:subfield> 
     <marc:subfield code="b">s.n. ,</marc:subfield> 
     <marc:subfield code="c">18--]</marc:subfield> 
    </marc:datafield> 
</marc:record> 
<marc:record> 
    <marc:leader>01290cem a2200313 a 4500</marc:leader> 
    <marc:controlfield tag="001">8108664</marc:controlfield> 
    <marc:datafield tag="260" ind1=" " ind2=" "> 
     <marc:subfield code="a">Torino :</marc:subfield> 
     <marc:subfield code="b">Editore Gio. Batt. Maggi ,</marc:subfield> 
     <marc:subfield code="c">1863.</marc:subfield> 
    </marc:datafield> 
</marc:record> 
</marc:collection> 
+0

「不知道放在這裏?」 'substring(1,string-length(marc:datafield [@ tag = 260]/marc:subfield [@ code ='b']) - 1)'工作嗎? – Pawel

+0

我會盡力......但首先我想我的測試語句的語法錯誤,但是,這阻止了正確編譯樣式表。我得到錯誤:「在令牌開始的意外冒號」 –

+0

好吧,我想我找到了「意外冒號...」的錯誤,現在我有:''。請原諒我,如果這是一個愚蠢的問題@Pawel,但我應該在你的建議的東西附上一行嗎?我試圖插入它,它只返回一個空標籤。 –

回答

4

ends-with()接受一個簡單的字符串,而不是一個正則表達式。這就是爲什麼你有問題:

ends-with(marc:datafield[@tag=260]/marc:subfield[@code='b'],'.|:|,') 

如果你想使用正則表達式,然後使用matches()

marc:datafield[@tag=260]/marc:subfield[@code='b']/matches(.,'^.*[\.:,]$') 

,並刪除使用replace()

replace('Ends with punctuation.', '^(.*)[\.:,]$', '$1') 
=> 
Ends with punctuation 

它也將可能會更簡單,只是在每個節點上執行替換,而不是先用if進行測試,因爲不匹配的情況不會進行替換,這似乎是行爲無論如何你是想要的。

+0

啊哈!謝謝@wst,這很好用。 –

2

一個通用的解決方案存在,這並不需要預先知道什麼都結束標點符號

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

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

<xsl:template match="text()[matches(., '^.*\p{P}$')]"> 
    <xsl:sequence select="replace(., '(^.*)\p{P}$', '$1')"/> 
</xsl:template> 
</xsl:stylesheet> 

當這一轉型是這個XML文檔施加:

<x> 
    <t>Some text .</t> 
    <t>Some text2 ;</t> 
    <t>Some text3 (</t> 
    <t>Some text4 !</t> 
    <t>Some text5 "</t> 
</x> 

想要的,正確的結果產生:

<x> 
     <t>Some text </t> 
     <t>Some text2 </t> 
     <t>Some text3 </t> 
     <t>Some text4 </t> 
     <t>Some text5 </t> 
</x> 

說明

正確使用p{P}字符類/類別。

\p是爲跳轉爲標點類別。 P所有標點符號屬性。

更新

的OP提供特定的源XML文檔和她的轉換代碼。

這裏是她的代碼,用上述溶液修改:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:marc="http://www.loc.gov/MARC21/slim" > 
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

<xsl:template match="/"> 
<xsl:for-each select="marc:collection/marc:record"> 
    <xsl:result-document method="xml" href="banana_{marc:controlfield[@tag=001]}.xml"> 
    <metadata> 
     <xsl:apply-templates select="self::marc:record"/> 
    </metadata> 
    </xsl:result-document> 
</xsl:for-each> 
</xsl:template> 

<xsl:template match="marc:record"> 
    <pubinfo> 
    <xsl:variable name="vSub1" select="marc:datafield[@tag=260]/marc:subfield[@code='a']"/> 
    <xsl:variable name="vSub2" select="marc:datafield[@tag=260]/marc:subfield[@code='b']"/> 
    <pubplace><xsl:value-of select="replace($vSub1, '(^.*)\s\p{P}$', '$1')"/></pubplace> 
    <publish><xsl:value-of select="replace($vSub2, '(^.*)\s\p{P}$', '$1')" /></publish> 
    </pubinfo> 
</xsl:template> 

</xsl:stylesheet> 
+0

謝謝你的額外答案。我想我理解邏輯,但是我很難正確實施它。我有一些其他模板指定輸出如下:''那可以嗎?是否會影響其他模板的表現?我還想知道是否有辦法在結束標點符號的同時消除尾隨空格。 –

+0

@SusanPowell,人們不應該猜測你的確切代碼或XML文檔是什麼 - 歡迎你編輯問題並提供更多可代表的代碼+數據。至於消除尾隨空白,只需使用:''^。* \ s \ p {P} $''而不是''^ \ * p {P} $'' –

+0

對不起,我是新來的並忘記我可以編輯我的原始帖子:$現在更新更完整的代碼。同樣感謝您提供有關清除尾部空白的答案。 –