鉴于这段XML
<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date>
<dc:date>2012-07-04</dc:date>
我需要使用XSL只输出字符串不以 info:eu-repo
开头的年份。
我正在尝试这种方式,但它不起作用。我错了for-each
?
<xsl:if test="not(starts-with('dc:date', 'info:eu-repo'))">
<xsl:for-each select="dc:date">
<publicationYear>
<xsl:variable name="date" select="."/>
<xsl:value-of select="substring($date, 0, 5)"/>
</publicationYear>
</xsl:for-each>
</xsl:if>
答案 0 :(得分:19)
我猜您在'
查询中不需要start-with
,并且您可能希望以稍微不同的方式迭代日期:
<xsl:for-each select="dc:date">
<xsl:variable name="date" select="."/>
<xsl:if test="not(starts-with($date, 'info:eu-repo'))">
<publicationYear>
<xsl:value-of select="substring($date, 0, 5)"/>
</publicationYear>
</xsl:if>
</xsl:for-each>
答案 1 :(得分:1)
您还可以使用template-match
来获得所需内容,例如:
<xsl:template match="date[not(starts-with(.,'info:eu-repo'))]">
<xsl:value-of select="."/>
</xsl:template>
我有这个输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<list>
<date>info:eu-repo/date/embargoEnd/2013-06-12</date>
<date>2012-07-04</date>
</list>
并将此XSLT应用于它:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="text() | @*"/>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="date[not(starts-with(.,'info:eu-repo'))]">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
我得到了这个输出:
<?xml version="1.0" encoding="UTF-8"?>2012-07-04
祝你好运, 彼得
答案 2 :(得分:1)
使用(假设提供的XML片段是当前节点的子元素,并且只有一个元素具有所需的属性):
substring-before(*[not(starts-with(., 'info:eu-repo'))], '-')
基于XSLT的验证:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:copy-of select=
"substring-before(*[not(starts-with(., 'info:eu-repo'))], '-') "/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(提供的片段包装在单个顶部元素中并声明命名空间):
<t xmlns:dc="some:dc">
<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date>
<dc:date>2012-07-04</dc:date>
</t>
XPath表达式从顶部元素开始计算,此评估的结果将复制到输出:
2012
<强> II。多个具有所需属性的元素:
在这种情况下,无法使用单个XPath 1.0表达式生成所需数据。
此XSLT转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[not(starts-with(., 'info:eu-repo'))]/text()">
<xsl:copy-of select="substring-before(., '-') "/>
==============
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
应用于此XML文档时:
<t xmlns:dc="some:dc">
<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date>
<dc:date>2012-07-04</dc:date>
<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date>
<dc:date>2011-07-05</dc:date>
</t>
会产生想要的正确结果:
2012
==============
2011
==============
<强> III。 XPath 2.0单行
*[not(starts-with(., 'info:eu-repo'))]/substring-before(., '-')
当从最后一个XML文档的顶部元素(最近的上方)评估此XPath 2.0表达式时,生成所需年份:
2012 2011
基于XSLT 2.0的验证:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:sequence select=
"*[not(starts-with(., 'info:eu-repo'))]/substring-before(., '-')"/>
</xsl:template>
</xsl:stylesheet>
当对最后一个XML文档应用此转换时,将评估XPath表达式并将此评估的结果复制到输出:
2012 2011
<强> IV。最常见和最困难的案例:
现在,让我们来看看这个XML文档:
<t xmlns:dc="some:dc">
<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date>
<dc:date>2012-07-04</dc:date>
<dc:date>info:eu-repo/date/embargoEnd/2013-06-12</dc:date>
<dc:date>2011-07-05</dc:date>
<dc:date>*/date/embargoEnd/2014-06-12</dc:date>
</t>
我们仍希望获得其字符串值不以'info:eu-repo'开头的所有dc:date
元素的年份部分。但是,以前的解决方案都不能正常使用上面的最后一个dc:date
元素。
值得注意的是,想要的数据仍然可以通过单个XPAth 2.0表达式生成:
for $s in
*[not(starts-with(., 'info:eu-repo'))]/tokenize(.,'/')[last()]
return
substring-before($s, '-')
当从上述XML文档的顶部元素评估此表达式时,会生成所需的正确结果:
2012 2011 2014
这是基于XSLT 2.0的验证:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:sequence select=
"for $s in
*[not(starts-with(., 'info:eu-repo'))]/tokenize(.,'/')[last()]
return
substring-before($s, '-')
"/>
</xsl:template>
</xsl:stylesheet>