我有这个(部分)XML文件,名为a.opf:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="nl" unique-identifier="isbn-id" prefix="cc: http://creativecommons.org/ns# rendition: http://www.idpf.org/vocab/rendition/# ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title id="title">good book</dc:title>
<meta refines="#title" property="title-type">main</meta>
<meta property="ibooks:version">1.0.411</meta>
<dc:language>nl</dc:language>
<meta property="dcterms:modified">2014-05-24T21:58:45Z</meta>
<dc:publisher>none</dc:publisher>
</metadata>
</package>
我用这个样式表进行转换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="meta[@property='ibooks:version']">
<xsl:copy>
<xsl:analyze-string select="." regex="([0-9]*\.[0-9]*\.)([0-9]*)">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<xsl:value-of select="number(regex-group(2)) + 1"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:text>1.0.0</xsl:text>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
<xsl:template match="meta[@property='dcterms:modified']">
<xsl:copy>
<xsl:value-of select="current-dateTime()"/>
</xsl:copy>
</xsl:template>
为什么两个元模板从未执行过? 文件a.opf只是被复制了。
答案 0 :(得分:3)
您在XSLT中缺少名称空间声明。
在XML中,您可以从这个名称空间声明开始......
<package xmlns="http://www.idpf.org/2007/opf"
这意味着包元素,并且任何子元素(除了已经以 dc:为前缀的子元素)都属于该命名空间。
但是,在你的XSLT中,你要这样做......
<xsl:template match="meta[...]">
尝试匹配NO命名空间中的 meta 元素,这与XML中名称空间中的 meta 元素不同。
在XSLT 1.0中,您必须在XSLT中添加命名空间的声明以及前缀...
<xsl:stylesheet ...
xmlns:opf="http://www.idpf.org/2007/opf"
然后你可以在任何xpath表达式中使用这个前缀......
<xsl:template match="opf:meta[@property='dcterms:modified']">
但是,您使用的是XSLT 2.0,因此您只需将其添加到 xsl:stylesheet 元素
<xsl:stylesheet ...
xpath-default-namespace="http://www.idpf.org/2007/opf"
这意味着xpath表达式中的任何元素(例如模板匹配)都没有前缀,将被假定属于默认命名空间。
试试这个XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xpath-default-namespace="http://www.idpf.org/2007/opf">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="meta[@property='ibooks:version']">uuu
<xsl:copy>
<xsl:analyze-string select="." regex="([0-9]*\.[0-9]*\.)([0-9]*)">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<xsl:value-of select="number(regex-group(2)) + 1"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:text>1.0.0</xsl:text>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
<xsl:template match="meta[@property='dcterms:modified']">4444
<xsl:copy>
<xsl:value-of select="current-dateTime()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>