Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
798 views
in Technique[技术] by (71.8m points)

xml - How to iterate over IDREFS values in XSLT 1.0?

I have an xml that uses an IDREFS field. I need to extract those id to put their in their own element.

Here's the basic structure I think I need but I don't know what to use in the select functions.

<xsl:template match="node_With_IDREFS_field">
   <xsl:for-each select="EACH ID IN @idrefsField">
      <xsl:element name="newElement">
        <xsl:attribute name="ref"><xsl:value-of select="THE IDREF"/></xsl:attribute>
      </xsl:element>
   </xsl:for-each>
   <!-- keep rest of content -->
   <xsl:apply-templates select="@*|node()"/>
</xsl:template>

So the from this node

<node_With_IDREFS_field idrefsField="id1 id2"/>

The result would be

<node_With_IDREFS_field>
  <newElement ref="id1"/>
  <newElement ref="id2"/>
</node_With_IDREFS_field>

Thanks for your help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to tokenize the value of the idrefsField attribute. XSLT 1.0 has no native tokenize() function, so you need to call a recursive named template to do this for you:

<xsl:template match="node_With_IDREFS_field">
    <xsl:copy>
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="@idrefsField"/>
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/>
    <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
        <xsl:if test="$token">
            <newElement ref="{$token}"/>
        </xsl:if>
        <xsl:if test="contains($text, $delimiter)">
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:if>
</xsl:template>

Alternatively, if your processor supports it, you could use the EXSLT str:tokenize() extension function.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...