问题
I am trying to use analyze-string on elements that possibly contain children nodes. Here is a snippet of a source file:
<year>
1975 music
</year>
<year>
1985<genre>rock</genre>music
</year>
<year>
2005 music
</year>
And here is what I would like to get:
<year>
70's music
</year>
<year>
80's<genre>rock</genre> music
</year>
The following code correctly matches the 3 cases, but I am missing something to copy both the text and the possible children nodes under the year element:
<xsl:template match="year">
<xsl:variable name="item" select="."/>
<xsl:analyze-string select="." regex="19(\d)\d">
<xsl:matching-substring>
<xsl:variable name="decade">
<xsl:value-of select="concat(regex-group(1),'0''s')"/>
</xsl:variable>
<year>
<xsl:value-of select="concat($decade,regex-group(2))"/>
<genre><xsl:value-of select="$item/genre"/>
</genre>
</year>
</xsl:matching-substring>
<xsl:non-matching-substring> </xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
Here is what I get:
<year>70's<genre/></year>
<year>80's<genre>rock</genre></year>
Thanks in advance for any help!
回答1:
It seems to suffice to match on the text child for the year pattern:
<xsl:template match="year[not(matches(., $pattern))]"/>
<xsl:template match="year/text()[matches(., $pattern)]">
<xsl:value-of select="replace(., $pattern, '$10''s')"/>
</xsl:template>
That gives
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:param name="pattern" as="xs:string">19(\d)\d</xsl:param>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="year[not(matches(., $pattern))]"/>
<xsl:template match="year/text()[matches(., $pattern)]">
<xsl:value-of select="replace(., $pattern, '$10''s')"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/gWmuiJV gives the result
<root>
<year>
70's music
</year>
<year>
80's<genre>rock</genre>music
</year>
</root>
For an XSLT 2 compatible solution you would need to spell out the xsl:mode
declaration used as the identity transformation template, example for that at http://xsltransform.hikmatu.com/jyH9rLQ.
来源:https://stackoverflow.com/questions/52560281/xslt-analyze-string-on-text-with-children-nodes