XSLT string manipulation
Could someone tell me the easiest way to fix below ? I currently have a file containing a variety of ways to define cross references (basically links to other pages), and I want to convert 2 of them to a single format. Below XML is a simplified sample showing source format :
<Paras>
<Para tag="CorrectTag">
<local xml:lang="en">Look at this section <XRef XRefType="(page xx)">(page 36)</XRef> for more information</local>
</Para>
<Para tag="InCorrectTag">
<local xml:lang="en">Look at some other section (page <XRef XRefType="xx">52</XRef>) for more information</local>
</Para>
</Paras>
What I want to achieve is the following :
<Paras>
<Para tag="CorrectTag">
<local xml:lang="en">Look at this section <XRef XRefType="(page xx)" XRefPage="36"/> for more information</local>
</Para>
<Para tag="InCorrectTag">
<local xml:lang="en">Look at some other section <XRef XRefType="(page xx)" XRefPage="52"/> for more information</local>
</Para>
</Paras>
Using below xslt to transform the [XRef] element
<xsl:template match="XRef">
<xsl:copy>
<xsl:attribute 开发者_JAVA百科name="XRefType">(page xx)</xsl:attribute>
<xsl:choose>
<xsl:when test="@XRefType='(page xx)'">
<xsl:attribute name="XRefPage" select="substring-before(substring-after(.,'(page '),')')"/>
</xsl:when>
<xsl:when test="@XRefType='xx'">
<xsl:attribute name="XRefPage" select="."/>
</xsl:when>
</xsl:choose>
</xsl:copy>
</xsl:template>
already gives me this output :
<Paras>
<Para tag="CorrectTag">
<local xml:lang="en">Look at this section<XRef XRefType="(page xx)" XRefPage="36"/>for more information</local>
</Para>
<Para tag="InCorrectTag">
<local xml:lang="en">Look at some other section (page<XRef XRefType="(page xx)" XRefPage="52"/>) for more information</local>
</Para>
</Paras>
Which is already solving most of my problem but I'm stuck on how I would get the rest of the [local] element cleaned without removing too much other content.
What I need is something like : if the string "(page " is followed by an XRef element , then remove it. If the string ")" is preceded by an XRef element, remove it. Otherwise, don't touch them.
Any advice on how to tackle this ?
Thanks is advance !
You should be able to tackle that with templates e.g.
<xsl:template match="text()[ends-with(., '(page ')][following-sibling::node()[1][self::XRef]]">
<xsl:value-of select="replace(., '(page $', '')"/>
</xsl:template>
<xsl:template match="text()[starts-with(., ')')][preceding-sibling::node[1][self::XRef]">
<xsl:value-of select="substring(., 2)"/>
</xsl:template>
Of course you need to make sure that any templates for parent element of those text nodes do an apply-templates to process the child nodes.
精彩评论