Как с помощью XSLT / XPath создать список через запятую?

В основном вам нужно нечеткое сопоставление строк, см.

https://en.wikipedia.org/wiki/Approximate_string_matching

https: //www.datacamp.com/community/tutorials/fuzzy-string-python

На основании этого вы можете проверить, насколько похожи входные данные по сравнению с вашим словарем:

 from fuzzywuzzy import fuzz

 name = "nick"
 tomatch = ["Nick", "ick", "nik", "nic", "nck", "nickey", "njick", "nickk", "nickn"]
 for str in tomatch:
    ratio = fuzz.ratio(str.lower(), name.lower())
    print(ratio)

Этот код выдаст следующий результат:

100
86
86
86
86
80
89
89
89

Вы должны поэкспериментировать с различными коэффициентами и проверить, какие из ваших требований будут пропускать только одну букву

29
задан 08.10.2019, 12:32

7 ответов

Посмотрите на функции position(), count() и last(); например, test="position() < last()".

25
ответ дан 08.10.2019, 12:36
  • 1
    Взгляните на w3schools.com/xpath, у них есть несколько замечательных обзоров основного xpath синтаксиса и возможностей. – Rahul 08.10.2019, 12:36
  • 2
    У меня есть эта строка: <xsl:value-of select="@Courses"/>, который отображает весь CSV, но это doesn' t выглядят слишком удобными для пользователя. Там какой-либо путь к вместо запятой, разделите их новой строкой для каждого значения? – Si8 08.10.2019, 12:36
  • 3
    @SiKni8 создайте новый вопрос для этого. – Willie Wheeler 08.10.2019, 12:37
  • 4
    That' s точно, что я искал, Спасибо! Where' s наполняют как зарегистрированный так или иначе? Спецификация XPath? – Anders Sandvig 08.10.2019, 12:37
  • 5
    Я также должен был повторно подключить iPhone после изменения этих настроек. Большое спасибо! – KIR 12.05.2020, 03:20

Роберт дал классу not(position() = last()) ответ. Для этого требуется обработать весь текущий список узлов, чтобы получить размер контекста, а в больших входных документах это может заставить преобразование потреблять больше памяти. Поэтому я обычно инвертирую тест, чтобы быть первым

<xsl:for-each select="*">
  <xsl:if test="not(position() = 1)>, </xsl:if>
  <xsl:value-of select="."/>   
</xsl:for-each>
7
ответ дан 08.10.2019, 12:33
  • 1
    @BeWarned, если Вы can' t опускают апельсины в избранном операторе, затем решения с положением () не будут работать. Однако в этом подвергает сомнению нет никакого шаблона базирующегося exlucedes, так, чтобы doesn' t действительно применяются здесь. – jelovirt 08.10.2019, 12:34
  • 2
    положение ()! =last () won' t работа, если Вы хотите, исключают некоторые объекты в последовательности. Например, что произошло бы, если список как это: < list> < apple> delicious</apple> < banana> dole</banana> < orange> navel</orange> </list> с шаблоном < обработайте по шаблону соответствуют =" orange"/> исключить апельсины. – BeWarned 08.10.2019, 12:35
  • 3
    I' m пытающийся думать, почему Вы wouldn' t хотят сделать это, и не придумывающий причину. – Robert Rossney 08.10.2019, 12:35
  • 4
    Для меня я должен был обновить к последней версии Safari (7.1) для отладки Safari на моем iPad рабочий iOS 8. – Liam 12.05.2020, 03:23

Простой однострочный XPath 1.0 :

& nbsp; & nbsp; & nbsp; & nbsp; concat(., substring(',', 2 - (position() != last())))

Положите его в это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

    <xsl:template match="/*">
      <xsl:for-each select="*">
        <xsl:value-of select=
         "concat(., substring(',', 2 - (position() != last())))"
         />
      </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

и примените его к документу XML :

<root>
    <item>apple</item>
    <item>orange</item>
    <item>banana</item>
</root>

, чтобы получить желаемый результат:

apple,orange,banana

РЕДАКТИРОВАТЬ:

Вот комментарий Роберта Росни к этому ответу:

Это довольно непрозрачно код для человека, чтобы читать. Это требует, чтобы вы знали две неочевидные вещи о XSLT: 1) что делает функция подстроки, если ее индекс выходит за пределы диапазона, и 2) что логические значения могут быть неявно преобразованы в числовые.

и вот мой ответ :

Ребята, никогда не стесняйтесь узнавать что-то новое. На самом деле, это все о переполнении стека, не так ли? :)

7
ответ дан 08.10.2019, 12:34
  • 1
    That' s довольно непрозрачный код для человека для чтения. Это требует, чтобы Вы знали две неочевидных вещи о XSLT: 1) что делает функция подстроки, если ее индекс вне диапазона и 2) тот логические значения могут быть неявно преобразованы в числовые. – Robert Rossney 08.10.2019, 12:34
  • 2
    Robert-Rossney Несомненно, часть его значения находится точно в этом! – Dimitre Novatchev 08.10.2019, 12:35
  • 3
    Я нашел, что в Настройках Safari на iPhone I также должен был Очистить Историю, и Ясные Cookie и Данные. – Bill Keller 12.05.2020, 03:22
<xsl:if test="following-sibling::*">,</xsl:if>

или (возможно, более эффективно, но вам придется проверить):

<xsl:for-each select="*[1]">
   <xsl:value-of select="."/>
   <xsl:for-each select="following-sibling::*">
       <xsl:value-of select="concat(',',.)"/>
   </xsl:for-each>
</xsl:for-each>
9
ответ дан 08.10.2019, 12:34
  • 1
    Вы могли уточнить то, что на самом деле делает тот тест? – Anders Sandvig 08.10.2019, 12:35
  • 2
    что-то:: указывает на ось - в этом случае, ось следовать-одноуровневого-элемента. Существуют различные оси - ось следовать-одноуровневого-элемента является теми узлами с тем же родителем, которые следуют за текущим узлом в порядке документа. Это проверяет на существование любых таких узлов. Если существует not' t любой, we' ре последнее. – Marc Gravell♦ 08.10.2019, 12:35
  • 3
    Это работает, но " положение () =last () " doesn' t должны создать набор узлов и затем протестировать его. Процессор XSLT не мог бы быть достаточно умным, чтобы знать что это isn' t собирающийся должен составлять список каждого после узла, и если это делает, который делает его (примерно) O (n^2) операция. – Robert Rossney 08.10.2019, 12:35
  • 4
    I' ll отправляют альтернативу, тогда;-p – Marc Gravell♦ 08.10.2019, 12:36
  • 5
    (Конечно, я имел в виду " положение ()! = в последний раз () ". дьявол находится в деталях.) – Robert Rossney 08.10.2019, 12:36
  • 6
    @derrylwc Вы подразумеваете, что не могли способный отладить UIWebViews в приложении с помощью опций разработчика Safari в Mac из-за недавнего обновления?... – Easwaramoorthy K 12.05.2020, 03:22

Для опции XSLT 2.0 вы можете использовать атрибут separator в xsl:value-of.

Это xsl:value-of:

<xsl:value-of select="/root/item" separator=", "/>

будет выдавать этот вывод:

apple, orange, banana

Вы также можете использовать больше, чем просто запятую для разделителя. Например, это:

<xsl:text>'</xsl:text>
<xsl:value-of select="/root/item" separator="', '"/>
<xsl:text>'</xsl:text>

выдаст следующий вывод:

'apple', 'orange', 'banana'

Другой вариант XSLT 2.0 - string-join() ...

<xsl:value-of select="string-join(/*/item,', ')"/>
11
ответ дан 08.10.2019, 12:35
  • 1
    Какие-либо другие причины, почему это не могло бы работать? I' m убедил, что эта функция стала немного прерванной недавний Safari (настольное) обновление. Я вижу представления Safari, но не UIWebViews в рамках другого приложения – derrylwc 12.05.2020, 03:21

Это довольно распространенная модель:

<xsl:for-each select="*">
   <xsl:value-of select="."/>
   <xsl:if test="position() != last()">
      <xsl:text>,</xsl:text>
   </xsl:if>
</xsl:for-each>
53
ответ дан 08.10.2019, 12:35
  • 1
    Я обновил свой ответ для отражения комментария к нему:) – Dimitre Novatchev 08.10.2019, 12:35
  • 2
    Это перестало работать если любое из значений you' итерация ре пуста. Это приведет к запаздыванию - или двойные запятые. – aaronbauman 08.10.2019, 12:36
  • 3
    @aaronbauman I wouldn' t вызов, что, перестав работать, а скорее отсутствие if not empty:) – Svish 08.10.2019, 12:36
  • 4
    это было моей проблемой, я пытался отладить производственное приложение, сделанное с ionic2. То, что я сделал, было: 1.ionic build ios, 2. подключите de iPad к ПК тогда в XCode I' ve выбрал устройство; 3. Develop> Выполненный – sTx 12.05.2020, 03:20

Вот так у меня получилось. Я проверил это по твоему списку:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

<xsl:template match="root">
    <xsl:call-template name="comma-join"><xsl:with-param name="list" select="item"/></xsl:call-template>
</xsl:template>

<xsl:template name="comma-join">
    <xsl:param name="list" />
    <xsl:for-each select="$list">
        <xsl:value-of select="." />
        <xsl:if test="position() != last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template> 
</xsl:stylesheet>
2
ответ дан 08.10.2019, 12:36
  • 1
    Я couldn' t находят установку упомянутой в этом сообщении (iOS 9), но отключение " не Делайте track" казалось, починил вещи – james246 12.05.2020, 03:23

Теги

Похожие вопросы