XSLT - «апостроф» не может использоваться в функции tokenize () - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть такие xml-элементы,

<p>'data1':'2','data2':'Sports like Cricker, Hokey',</p>

Мне нужно разбить эти элементы на несколько <p> элементов следующим образом:

<p>'data1':'2'</p>
<p>'data2':'Sports like Cricket, Hokey',</p>

Я написал следующееXSLT для выполнения этой задачи,

<xsl:template match="p">
        <xsl:variable name="tokens" select="tokenize(., ',')"/>
        <xsl:for-each select="$tokens">
            <xsl:analyze-string select="." regex="^&apos;(.*)&apos;:&apos;(.*)$">
                <xsl:matching-substring>
                    <p>
                        <xsl:value-of select="."/>
                    </p>
                </xsl:matching-substring>
            </xsl:analyze-string>
        </xsl:for-each>
    </xsl:template>

Этот код отлично работает, когда , не отображается в середине текста.(например: «Спорт, как крикет, хоккей»).Но если в тексте есть ,, это сломается, как в этом примере.

Я попытался использовать функцию токенизации следующим образом, но, похоже, апостроф не разрешен в функции tokenize () в XSLT.

tokenize (., '', ')

Кто-нибудь может предложить мне решение для этого?

1 Ответ

1 голос
/ 02 апреля 2019

Одна из причин, по которой ваш скрипт потерпел неудачу, заключается в том, что вы использовали &apos; вместо простого апострофа (&apos; используется при записи вывода, но в регулярном выражении используется только ').

Другая причинаВо втором источнике <p> видно, что после завершающего ' у вас есть запятая, а регулярное выражение заканчивается на $.

Таким образом, регулярное выражение может быть, например:

'([^']+)'\s*:\s*'([^']+)'

Подробности:

  • Апостроф (открытие).
  • Непустая последовательность символов, отличная от апостроф.
  • Апостроф (закрытие).
  • Двоеточие, возможно, окруженное пробелами.
  • Та же конструкция, что и для "первой" части (перед двоеточием).

Ниже у вас естьпример сценария:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="p">
    <xsl:analyze-string select="." regex="'([^']+)'\s*:\s*'([^']+)'">
      <xsl:matching-substring>
        <p><xsl:value-of select="concat(regex-group(1),
          ' / ', regex-group(2))"/></p>
      </xsl:matching-substring>
    </xsl:analyze-string>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Для данных источника, как показано ниже:

<?xml version="1.0" encoding="utf-8" ?>
<body>
  <p>'data1':'2','data3':'5'</p>
  <p>'data2':'Sports like Cricket, Hokey',</p>
</body> 

выводит:

<?xml version="1.0" encoding="UTF-8"?>
<body>
   <p>data1 / 2</p>
   <p>data3 / 5</p>
   <p>data2 / Sports like Cricket, Hokey</p>
</body>

Обратите внимание, что первый источник <p> содержит два ключ: значение пар, которые являются источником двух первых выводных <p> элементов.

...