开发者

XSLT string manipulation

开发者 https://www.devze.com 2023-04-06 21:29 出处:网络
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 t

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消