Ist XSLT eine Split () Funktion haben?
Frage
Ich habe eine Zeichenfolge in einem Knoten, und ich möchte die Zeichenfolge auf aufzuspalten ‚?‘ und zurück auf das letzte Element im Array.
Zum Beispiel im Block unter:
<a>
<xsl:attribute name="href">
/newpage.aspx?<xsl:value-of select="someNode"/>
</xsl:attribute>
Link text
</a>
Ich möchte den someNode
Wert teilen.
Edit: Hier ist die VB.Net, die ich benutze die Xsl für meine Asp.Net Seite zu laden:
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: ist hier ein Beispiel Splitting XML auf einem bestimmten Knoten
Lösung
eine rekursive Methode verwenden:
<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>
Andere Tipps
Wenn Sie XSLT 2.0 oder höher verwenden, können Sie tokenize(string, separator)
verwenden:
tokenize("XPath is fun", "\s+")
Result: ("XPath", "is", "fun")
Siehe w3schools XPath-Funktion Referenz .
Standardmäßig wird .NET unterstützt XSLT 2.0, geschweige denn XSLT 3.0. Die einzigen bekannten 2.0+ Prozessoren für .NET sind Saxon für .NET mit IKVM , Exselt , ein .NET XSLT 3.0 Prozessor derzeit in der beta und XMLPrime XSLT 2.0 Prozessor.
Ich landete mit der substring-after()
Funktion . Hier ist, was für mich gearbeitet:
<a>
<xsl:attribute name="href">
/newpage.aspx?<xsl:value-of select="substring-after(someNode, '?')"/>
</xsl:attribute>
Link text
</a>
Auch nach der Version meines XSLT 2.0 Einstellung, ich habe noch einen „'tokenize()' is an unknown XSLT function.
“ Fehler beim Versuch tokenize()
zu verwenden.
Eine weitere Möglichkeit hinzufügen, wenn Ihre Template-Engine EXSLT , dann könnte man a href verwenden <= "http :. //www.exslt.org/str/functions/tokenize/index.html“rel = "noreferrer"> tokenize () aus, dass
Zum Beispiel:
<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>
.NET nicht unterstützt XSLT 2.0, leider. Ich bin mir ziemlich sicher, dass es unterstützt EXSLT, die eine Split rel="nofollow () Funktion. Microsoft hat eine ältere über die Umsetzung von EXSLT.
Sie können eine Vorlage mit string-before
und string-after
Funktionen schreiben und verwenden Sie es über. Ich schrieb ein Blog zu diesem Thema.
Schließlich kam mit einer XSLT-Vorlage auf, die eine getrennte Zeichenfolge in Teil aufgeteilt würden. Ich behaupte nicht, dass es das Klügste, Skript, aber sicher löst mein Problem.
Sheet:
<?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-Datei (zu transformierenden):
<?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>
XSLT 1.0 verfügt nicht über eine Split-Funktion per se, aber Sie könnten möglicherweise erreichen, was Sie versuchen, mit den substring-before und substring-after-Funktionen zu tun.
Alternativ, wenn Sie einen Microsoft XSLT-Engine verwenden, können Sie Inline C # verwenden.
Nur für das Protokoll, wenn Sie diese mit 1,0 tun, und Sie müssen wirklich einen Split / tokenise, müssen Sie die xslt Erweiterungen .