У меня есть строка в узле, и я хотел бы разбить строку на '?' и вернуть последний элемент в массиве.
Например, в блоке ниже:
<a>
<xsl:attribute name = "href">
/newpage.aspx?<xsl:value-of select = "someNode"/>
</xsl:attribute>
Link text
</a>
Я бы хотел разделить значение someNode.
Редактировать: Вот VB.Net, который я использую для загрузки Xsl для моей страницы Asp.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()
Обновлять: вот пример разделения XML на конкретный узел





Если вы можете использовать XSLT 2.0 или выше, вы можете использовать tokenize(string, separator):
tokenize("XPath is fun", "\s+")
Result: ("XPath", "is", "fun")
См. Справочник по функциям XPath в w3schools.
По умолчанию .NET не поддерживает XSLT 2.0, не говоря уже о XSLT 3.0. Единственные известные процессоры 2.0+ для .NET - это Saxon для .NET с ИКВМ, Exselt, процессор .NET XSLT 3.0, который в настоящее время находится в стадии бета-тестирования, и процессор XMLPrime XSLT 2.0.
Единственный недостаток в том, что для этого требуется XSLT 2.0 :-(
да, я получаю сообщение «tokenize () - неизвестная функция XSLT». ошибка
Какой процессор вы используете?
XSLT 1.0 не имеет функции разделения как таковой, но вы потенциально можете достичь того, что пытаетесь сделать, с помощью функций substring-before и substring-after.
В качестве альтернативы, если вы используете механизм Microsoft XSLT, вы можете использовать встроенный C#.
В итоге я использовал функцию substring-after(). Вот что у меня сработало:
<a>
<xsl:attribute name = "href">
/newpage.aspx?<xsl:value-of select = "substring-after(someNode, '?')"/>
</xsl:attribute>
Link text
</a>
Даже после установки версии моего XSLT на 2.0 я все еще получал ошибку «'tokenize()' is an unknown XSLT function.» при попытке использовать tokenize().
Мне жаль, что я не сохранил код, но у моего предыдущего работодателя я написал функцию xslt 1.0 для получения n-го токена строки. Это не так уж и сложно, если вы погрузитесь в концепцию функционального программирования.
Для записи: если вы делаете это с 1.0 и вам действительно нужен разделение / токенизация, вам понадобится xslt расширения.
интересно, как бы я использовал это в примере выше?
Используйте рекурсивный метод:
<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>
Работал как шарм. Спасибо!
Обратите внимание, что если в списке нет токенов, этот шаблон тем не менее будет выводить пустой элемент <id> вместо элементов <id>.
Я был очень рад попробовать это, но Firefox, к сожалению, сообщает: «Ошибка при преобразовании XSLT: таблица стилей XSLT (возможно) содержит рекурсию». Да, Firefox должен быть рекурсивным ... да ...
К сожалению, .NET не поддерживает XSLT 2.0. Я почти уверен, что он поддерживает EXSLT, в котором есть функция расколоть(). У Microsoft есть старая страница по реализации EXSLT.
Добавим еще одну возможность, если ваш шаблонизатор поддерживает EXSLT, тогда вы можете использовать tokenize () из этого.
Например:
<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?
Вы можете написать шаблон, используя функции string-before и string-after, и использовать его повсюду. Я написал об этом блог.
Наконец, появился шаблон xslt, который разделял строку с разделителями на подстроки. Я не утверждаю, что это самый умный сценарий, но, безусловно, решает мою проблему.
Таблица стилей:
<?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-файл (подлежит преобразованию):
<?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>
На самом деле не имеет ничего общего с ASP.Net