xslt删除结尾标点符号
我正在编写一个xslt样式表,将MARC xml记录转换为FGDC xml元数据。很多MARC字段的末尾都有多余的标点符号(句号、冒号、逗号等),我想去掉这些标点符号。不过,我不想删除行中的所有标点符号。我的想法是用if语句编写一个模板,并测试字段是否以指定字符结尾,然后将其删除,但我不确定:1)这是否是一个好方法,2)如何指定该过程 已编辑我的xslt:xslt删除结尾标点符号,xslt,xslt-2.0,Xslt,Xslt 2.0,我正在编写一个xslt样式表,将MARC xml记录转换为FGDC xml元数据。很多MARC字段的末尾都有多余的标点符号(句号、冒号、逗号等),我想去掉这些标点符号。不过,我不想删除行中的所有标点符号。我的想法是用if语句编写一个模板,并测试字段是否以指定字符结尾,然后将其删除,但我不确定:1)这是否是一个好方法,2)如何指定该过程 已编辑我的xslt: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:
<?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文档(或至少是其中的一部分):
01502cfm a2200313 a 4500
7943586
[S.l.:
s、 n,
18--]
01290cem a2200313 a 4500
8108664
都灵:
伊迪托雷·吉奥。巴特。马吉,
1863
以()结尾。
接受简单字符串,而不是正则表达式。这就是您在以下方面遇到问题的原因:
ends-with(marc:datafield[@tag=260]/marc:subfield[@code='b'],'.|:|,')
如果要使用正则表达式,请使用matches()
:
要删除,请使用replace()
:
在每个节点上执行替换也可能更简单,而不是先使用if进行测试,因为不匹配的情况不会执行替换,这似乎是您想要的行为。存在一个通用解决方案,不需要预先知道结尾标点符号是什么:
<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>
<x>
<t>Some text .</t>
<t>Some text2 ;</t>
<t>Some text3 (</t>
<t>Some text4 !</t>
<t>Some text5 "</t>
</x>
<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>
“不确定这里是什么?”
子字符串(1,字符串长度(marc:datafield[@tag=260]/marc:subfield[@code='b'])-1)
有效吗?我会试试。。。但是首先,我认为我的test语句的语法中有一个错误,这妨碍了样式表的正确编译。我得到一个错误:“令牌开头的意外冒号”好的,我想我找到了“意外冒号…”错误,我现在有:
。如果这是一个愚蠢的问题,请原谅我@Pawel,但我是否应该将你建议的那条线包含在某些内容中?我试着按原样插入它,但它只返回了一个空标记。我认为这是一个输入错误(我不知道您可以使用XSLT2.0)。不管怎样,下面的答案似乎就是你想要的。谢谢你的补充答案。我想我理解这个逻辑,但我在正确实现它时遇到了困难。我有一些其他模板指定输出,如:
这会影响其他模板的表达方式吗?我还想知道是否有一种方法可以在结束标点符号的同时消除尾随空格。@SusanPowell,你不应该猜测你的确切代码或XML文档是什么——欢迎你编辑这个问题并提供更具代表性的代码+数据。至于消除尾随空格,只需使用:'^..*\s\p{p}$'
而不是'^..*\p{p}$'
很抱歉,我是新来的,忘了我可以编辑我的原始帖子:$现在用更完整的代码更新了。还感谢您回答有关删除尾随空格的问题。@SusanPowell,我已经修改了您的代码,现在它适用于任何结尾标点符号,无需事先了解可能的标点符号,也无需在每次数据中出现新标点符号时修改代码。看到我更新的答案。谢谢你的帮助@迪米特里·诺瓦切夫
<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>
<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>
<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>