.net XSLT 有 Split() 函数吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/136500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:05:15  来源:igfitidea点击:

Does XSLT have a Split() function?

.netxmlvb.netxsltsplit

提问by travis

I have a string in a node and I'd like to split the string on '?' and return the last item in the array.

我在一个节点中有一个字符串,我想在 '?' 上拆分字符串。并返回数组中的最后一项。

For example, in the block below:

例如,在下面的块中:

<a>
    <xsl:attribute name="href">
        /newpage.aspx?<xsl:value-of select="someNode"/>
    </xsl:attribute>
    Link text
</a>

I'd like to split the someNodevalue.

我想分割someNode价值。

Edit: Here's the VB.Net that I use to load the Xsl for my Asp.Net page:

编辑:这是我用来为我的 Asp.Net 页面加载 Xsl 的 VB.Net:

Dim xslDocPath As String = HttpContext.Current.Server.MapPath("~/App_Data/someXslt.xsl")
Dim myXsltSettings As New XsltSettings()
Dim myXMLResolver As New XmlUrlResolver()

myXsltSettings.EnableScript = True
myXsltSettings.EnableDocumentFunction = True

myXslDoc = New XslCompiledTransform(False)
myXslDoc.Load(xslDocPath, myXsltSettings, myXMLResolver)

Dim myStringBuilder As New StringBuilder()
Dim myXmlWriter As XmlWriter = Nothing

Dim myXmlWriterSettings As New XmlWriterSettings()
myXmlWriterSettings.ConformanceLevel = ConformanceLevel.Auto
myXmlWriterSettings.Indent = True
myXmlWriterSettings.OmitXmlDeclaration = True

myXmlWriter = XmlWriter.Create(myStringBuilder, myXmlWriterSettings)

myXslDoc.Transform(xmlDoc, argumentList, myXmlWriter)

Return myStringBuilder.ToString()

Update:here's an example of splitting XML on a particular node

更新:这是在特定节点上拆分 XML 的示例

回答by mortenbpost

Use a recursive method:

使用递归方法:

<xsl:template name="output-tokens">
    <xsl:param name="list" /> 
    <xsl:variable name="newlist" select="concat(normalize-space($list), ' ')" /> 
    <xsl:variable name="first" select="substring-before($newlist, ' ')" /> 
    <xsl:variable name="remaining" select="substring-after($newlist, ' ')" /> 
    <id>
        <xsl:value-of select="$first" /> 
    </id>
    <xsl:if test="$remaining">
        <xsl:call-template name="output-tokens">
            <xsl:with-param name="list" select="$remaining" /> 
        </xsl:call-template>
    </xsl:if>
</xsl:template>

回答by Jacob

If you can use XSLT 2.0 or higher, you can use tokenize(string, separator):

如果您可以使用 XSLT 2.0 或更高版本,则可以使用tokenize(string, separator)

tokenize("XPath is fun", "\s+")
Result: ("XPath", "is", "fun")

See the w3schools XPath function reference.

请参阅w3schools XPath 函数参考

By default, .NET does not support XSLT 2.0, let alone XSLT 3.0. The only known 2.0+ processors for .NET are Saxon for .NETwith IKVM, Exselt, a .NET XSLT 3.0 processor currently in beta, and XMLPrimeXSLT 2.0 processor.

默认情况下,.NET 不支持 XSLT 2.0,更不用说 XSLT 3.0。唯一已知的用于 .NET 的 2.0+ 处理器是用于 .NET 的SaxonIKVMExselt、目前处于测试阶段的 .NET XSLT 3.0 处理器和XMLPrimeXSLT 2.0 处理器。

回答by travis

I ended up using the substring-after()function. Here's what worked for me:

我最终使用了该substring-after()功能。以下是对我有用的内容:

<a>
    <xsl:attribute name="href">
        /newpage.aspx?<xsl:value-of select="substring-after(someNode, '?')"/>
    </xsl:attribute>
    Link text
</a>

Even after setting the version of my XSLT to 2.0, I still got a "'tokenize()' is an unknown XSLT function." error when trying to use tokenize().

即使将我的 XSLT 版本设置为 2.0,我'tokenize()' is an unknown XSLT function.在尝试使用tokenize().

回答by Paul Wagland

Adding another possibility, if your template engine supports EXSLT, then you could use tokenize()from that.

添加另一种可能性,如果您的模板引擎支持EXSLT,那么您可以从中使用tokenize()

For example:

例如:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:str="http://exslt.org/strings"
                extension-element-prefixes="str">

...
  <a>
    <xsl:attribute name="href">
      <xsl:text>/newpage.aspx?</xsl:text>
      <xsl:value-of select="str:tokenize(someNode)[2]"/>
    </xsl:attribute>              
  </a>
...
</xsl:stylesheet>

回答by James Sulak

.NET doesn't support XSLT 2.0, unfortunately. I'm pretty sure that it supports EXSLT, which has a split()function. Microsoft has an older pageon its implementation of EXSLT.

不幸的是,.NET 不支持 XSLT 2.0。我很确定它支持 EXSLT,它有一个split()函数。微软有一个关于 EXSLT 实现的旧页面

回答by Lav G

You can write a template using string-beforeand string-afterfunctions and use it across. I wrote a blogon this.

您可以使用string-beforestring-after函数编写模板并使用它。我写了一篇关于这个的博客

Finally came up with a xslt template that would split a delimited string into substrings. I don't claim it's the smartest script, but surely solves my problem.

最后想出了一个 xslt 模板,可以将分隔的字符串拆分为子字符串。我不声称它是最聪明的脚本,但肯定能解决我的问题。

Stylesheet:

样式表:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="Paths/Item">
<xsl:call-template name="SplitText">
<xsl:with-param name="inputString" select="Path"/>
<xsl:with-param name="delimiter" select="Delimiter"/>
</xsl:call-template>
<br/>
</xsl:for-each>
</xsl:template>
<xsl:template name="SplitText">
<xsl:param name="inputString"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($inputString, $delimiter)">
<xsl:value-of select="substring-before($inputString,$delimiter)"/>
<xsl:text disable-output-escaping = "no"> </xsl:text>
<xsl:call-template name="SplitText">
<xsl:with-param name="inputString" select="substring-after($inputString,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$inputString = ''">
<xsl:text></xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$inputString"/>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

XML file (to be transformed) :

XML 文件(待转换):

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="textSpliter.xslt"?>
<Paths>
  <Item>
    <Path>C:\ProgramFiles\SomeWierdSoftware</Path>
    <Delimiter>\</Delimiter>
  </Item>
</Paths> 

回答by AmbroseChapel

Just for the record, if you're doing this with 1.0, and you really need a split/tokenise, you need the xslt extensions.

只是为了记录,如果您使用 1.0 执行此操作,并且您确实需要拆分/标记化,则需要xslt 扩展名

回答by Greg Beech

XSLT 1.0 doesn't have a split function per se, but you could potentially achieve what you're trying to do with the substring-before and substring-after functions.

XSLT 1.0 本身没有拆分函数,但是您可以通过 substring-before 和 substring-after 函数潜在地实现您想要做的事情。

Alternatively, if you're using a Microsoft XSLT engine, you could use inline C#.

或者,如果您使用的是 Microsoft XSLT 引擎,则可以使用内联 C#。