问题描述
我正在尝试从一个大字符串中为某个变量分配一个特定的标记.我首先将字符串标记化,然后针对每个标记检查它是否包含某个子字符串.如果是这样,我想将该令牌分配给该变量.
I'm trying to assign a variable a certain token from a large string. I first tokenize the string, then for each token I check if it contains a certain substring. If it does, I want to assign that token to the variable.
最后,我使用该变量设置div的属性.
Lastly, I use that variable to set an attribute of a div.
我已经在下面尝试了这段代码,该代码可以在 oXygen XML编辑器
中提供我想要的确切输出.但是,当我在 IE
(11)中运行XML/XSLT文件时,它只是打印出整个原始字符串,在下面的XSLT中测量 xhtmlVar
.div甚至没有显示出来(它可能在DOM中,但是我看不到它-我会暂时重新检查).
I've tried this code below, which gives me the exact output i want in oXygen XML Editor
. However, when I run the XML/XSLT file in IE
(11), it simply just prints out the entire original string, meaing xhtmlVar
in the XSLT below. The div doesn't even show up (it might be there in DOM, but I don't visually see it -- I'll recheck this momentarily).
XSLT
<!-- xhtmlVar variable is a large string -->
<xsl:variable name="xhtmlVar" select="metadata[@element='xhtml_head_item']"></xsl:variable>
<xsl:variable name="quoteChar">"</xsl:variable> <!-- for cleaning token below -->
<xsl:variable name="tokenized" select="tokenize($xhtmlVar,' ')"/>
<xsl:variable name="doi">
<xsl:for-each select="$tokenized">
<xsl:variable name="curtoken" select="."/>
<!-- if token contains the string 'doi', assign it to the variable -->
<xsl:if test="contains($curtoken, 'doi')">
<!-- return value while stripping some stuff (token looks like this: doi:asdasdasd") -->
<xsl:value-of select="translate(replace($curtoken, 'doi:', ''),$quoteChar,'')"></xsl:value-of>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!-- pass $doi variable as attribute value in a div -->
<div type='medium' class='embed' handle='{$doi}'></div>
如何实现我想要的?难道我做错了什么?任何有关如何更优雅地编写上述代码的技巧也将受到赞赏!
How can I achieve what I want? Am I doing something wrong? Any tips on how to more gracefully write the code above is also appreciated!
提前谢谢!
更新:
我已将代码更改为使用EXSLT,如下面的Martin Honnen所建议.
I've changed my code to use EXSLT, as suggested by Martin Honnen below.
但是,现在令牌化模板似乎只是删除了指定的分隔符,而不是实际将其用作分隔符.另外,我不知道如何使用空格作为定界符:
However, now the tokenize template seems to simply remove the specified delimiter instead of actually using it as a delimiter. Also, I can't figure out how to use a whitespace as a delimiter:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:exsl="http://exslt.org/common"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="exsl str"
exclude-result-prefixes="xs"
version="1.0">
<xsl:import href="str/str.xsl" />
<xsl:import href="str.tokenize/str.tokenize.template.xsl" />
...
<xsl:variable name="quoteChar">"</xsl:variable>
<xsl:variable name="spaceChar"> </xsl:variable>
<xsl:variable name="tokenized">
<xsl:call-template name="str:tokenize">
<xsl:with-param name="string" select="$xhtmlVar" />
<xsl:with-param name="delimiters" select="','" />
</xsl:call-template>
</xsl:variable>
<!-- prevent tree fragment error with exsl:node-set -->
<xsl:for-each select="exsl:node-set($tokenized)">
<xsl:variable name="curtoken" select="."/>
<xsl:value-of select="$curtoken"/>
<xsl:text> Ha </xsl:text>
<!-- Nevermind checking if each token contains what I want for now...
<xsl:if test="contains($curtoken, 'doi')">
<xsl:value-of select="translate(str:replace($curtoken, 'doi:', ''),$quoteChar,'')"></xsl:value-of>
</xsl:if>-->
</xsl:for-each>
上面的代码将打印出整个字符串(每个令牌),但是不会删除逗号分隔符,",而是打印出由单词"Ha"分隔的每个令牌.然后,"Ha"出现在最后.我是否可能错误地使用了 node-set
函数?
Instead of printing out each token separated by the word "Ha", the code above will print out the entire string (every token) but the comma delimiter "," will be removed. "Ha" then appears at the very end. Am I perhaps using the node-set
function incorrectly?
此外,如果我尝试使用诸如 $ spaceChar
之类的定界符或诸如'than'
之类的整个单词,我通常会得到一些类似于模板"的东西指令堆栈溢出"错误.
Also, if I try to use delimiters like $spaceChar
or an entire word, such as 'than'
, I often get something along the lines of a "template instruction stack overflow" error.
每个michael.hor的答案的代码有效.
Code per michael.hor 's answer works.
像这样使用 str:replace()
<xsl:value-of select="translate(str:replace($curtoken, 'doi:', ''),$quoteChar,'')"/>
尽管如此,还是给了我oXygen XML错误:
Gives me this error in oXygen XML, though:
Severity: fatal
Description: java.lang.NoSuchMethodException: For extension function, could not find method org.apache.xalan.lib.ExsltStrings.replace([ExpressionContext,] #NODESET, #STRING, #STRING).
Checked both static and instance methods. - For extension function, could not find method org.apache.xalan.lib.ExsltStrings.replace([ExpressionContext,] #NODESET, #STRING, #STRING).
Checked both static and instance methods.
推荐答案
重新输入问题:
如果您的处理器支持EXSLT str:tokenize()扩展功能,则:
If your processor supports the EXSLT str:tokenize() extension function, then:
- 您不需要导入任何内容;
- 您可以(并且应该)使用功能,而不是模板;和
- 该函数的结果已经是一个节点集.
尝试以下样式表作为测试(它可以与任何输入一起使用):
Try the following stylesheet as a test (it will work with any input):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="input" select="'some,comma,delimited,string'" />
<xsl:template match="/">
<xsl:variable name="tokenized" select="str:tokenize($input, ',')" />
<output>
<xsl:for-each select="$tokenized">
<xsl:value-of select="." />
<xsl:text> Ha </xsl:text>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
这篇关于在浏览器中使用的样式表中使用标记化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!