Как найти все числа в строке
Ich versuche mit einer Функциональная возможность Заработная плата Элемент под строку String zu ermitteln. Dabei soll die Die Anzahl der Zahlen und ihre Stelligkeit egal sein. Folgende Funktion habe ich bislang geschrieben:
<xsl:function name="itp:find_num">
<xsl:param name="tmp"/>
<xsl:if test="matches($tmp,'\d+')">
<xsl:analyze-string select="$tmp" regex="{'\d+'}">
<xsl:matching-substring>
<xsl:sequence select="."/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="''"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:if>
</xsl:function>
Beispiel XML:
<address>street 12, 12345 town<address>
Bei dem Funktionsaufruf soll dann die entsprechende Zahl ausgewählt werden können:
...select="itp:find_num(address)[2]"/>
Zum Beispiel die 2 für die Postleitzahl. Das Problem ist nun, dass in der Sequence aue leere Werte stehen, поэтому dass ich in der Praxis die Postleitzahl nur mit [4] erreiche.
Гибкость в том, что касается Möglichkeit meine Проблема zu lösen? И я не знаю, что у нас получилось. Elemente aus der Sequence??
Теперь на английском языке:-)
Я пытаюсь найти все числа в строке oder элемента. Не должно иметь значения, сколько чисел доступно или в какой позиции они находятся в строке.
Вот моя функция:
<xsl:function name="itp:find_num">
<xsl:param name="tmp"/>
<xsl:if test="matches($tmp,'\d+')">
<xsl:analyze-string select="$tmp" regex="{'\d+'}">
<xsl:matching-substring>
<xsl:if test=". != ''">
<xsl:sequence select="."/>
</xsl:if>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="''"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:if>
</xsl:function>
Пример XML
<address>street 12, 12345 town<address>
Когда я вызываю функцию, я хочу выбрать, какой номер я хочу выбрать:
...select="itp:find_num(address)[2]"/>
Например, [2] для почтового индекса. У меня проблема в том, что в последовательности есть пустые элементы, поэтому мне нужно выбрать [4], чтобы получить почтовый индекс.
Есть ли более простой способ решить мою проблему? Или есть способ удалить все пустые элементы в этой последовательности?
Спасибо:-)
2 ответа
Я бы написал функцию как
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.org/mf"
exclude-result-prefixes="xs mf">
<xsl:function name="mf:find_num" as="xs:integer*">
<xsl:param name="input" as="xs:string"/>
<xsl:analyze-string select="$input" regex="[0-9]+">
<xsl:matching-substring>
<xsl:sequence select="xs:integer(.)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="address">
<xsl:value-of select="mf:find_num(.)" separator=", "/>
</xsl:template>
</xsl:stylesheet>
Конечно, преобразование в xs:integer
необязательно, если вы хотите, чтобы функция возвращала последовательность строк, содержащих цифры, вы просто изменили бы ее на
<xsl:function name="mf:find_num" as="xs:string*">
<xsl:param name="input" as="xs:string"/>
<xsl:analyze-string select="$input" regex="[0-9]+">
<xsl:matching-substring>
<xsl:sequence select="."/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
Нет необходимости в сложном xsl:analyze-string
обработка вообще.
Этот XPath однострочный:
for $i in tokenize($pStr, '[^0-9]+')[.]
return xs:integer($i)
создает искомую последовательность целых чисел в строке:
12 12345
Вот полное преобразование:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:sequence select="my:nums(.)"/>
</xsl:template>
<xsl:function name="my:nums" as="xs:integer*">
<xsl:param name="pStr" as="xs:string"/>
<xsl:sequence select=
"for $i in tokenize($pStr, '[^0-9]+')[.]
return xs:integer($i)"/>
</xsl:function>
</xsl:stylesheet>
Когда это преобразование применяется к предоставленному документу XML:
<address>street 12, 12345 town</address>
желаемый, правильный результат получается:
12 12345
Еще проще, XPath 3.0 с одним вкладышем:
tokenize($pStr, '[^0-9]+')[.] ! xs:integer(.)