Заменить символ новой строки наXSL - PullRequest
2 голосов
/ 15 мая 2011

У меня есть список Sharepoint, который я хочу преобразовать в JSON через представление данных XSL.

У меня есть функция рекурсивной замены XSL, которую я использую для замены всех специальных символов (обратной косой черты, двойных кавычек на & quot; и т. Д.), Что дает мне хороший чистый JSON, который правильно анализируется в браузере пользователей.

Последнее, что мне нужно, чтобы избежать / заменить это новая строка char. Новая строка вызывает ошибки при разборе JSON в некоторых браузерах.

Вот некоторый xsl, который проверяет, имеет ли содержимое заголовка новую строку char, если он выводит абзац:

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

<xsl:template match="/">

    <xsl:for-each select="catalog/cd">

        <xsl:if test='contains(title,"&#xA;")'>   
                <p>Found <xsl:value-of select="title" /></p>
        </xsl:if>

    </xsl:for-each>

</xsl:template>
</xsl:stylesheet>

Вот пример XML:

<catalog>
    <cd>
        <title>Empire 
Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>

«Империя бурлеска» должна быть единственным элементом, который пройдет тест, но все три заголовка проходят оператор if и выводятся.

EDIT

Модифицируя решение, приведенное ниже, я полагаю, это должно работать, если я хочу выполнить поиск и замену для отдельных узлов? Я не смогу проверить это в Sharepoint до завтра.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
  <xsl:for-each select="catalog/cd">

  <xsl:variable name="title_clean">
    <xsl:call-template name="repNL">
      <xsl:with-param name="pText" select="title"/>
    </xsl:call-template>
  </xsl:variable>

  <p><xsl:value-of select='$title_clean' /></p>

  </xsl:for-each>
</xsl:template>


<xsl:template name="repNL">
  <xsl:param name="pText" select="."/>

  <xsl:copy-of select="substring-before(concat($pText,'&#xA;'),'&#xA;')"/>

  <xsl:if test="contains($pText, '&#xA;')">
  <br />
  <xsl:call-template name="repNL">
  <xsl:with-param name="pText" select=
  "substring-after($pText, '&#xA;')"/>
  </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Ответы [ 2 ]

2 голосов
/ 15 мая 2011

"Империя Бурлеск" должна быть единственным элементом, который пройдет тест, но все три заголовка проходят оператор if и выводятся.

Невозможно воспроизвести предполагаемую проблему - протестировано с 9 различными процессорами XSLT, включая все от Microsoft.

В любом случае:

Это преобразование заменяет любой символ NL в текстовом узле элементом br :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="text()" name="repNL">
  <xsl:param name="pText" select="."/>

  <xsl:copy-of select=
  "substring-before(concat($pText,'&#xA;'),'&#xA;')"/>

  <xsl:if test="contains($pText, '&#xA;')">
   <br />
   <xsl:call-template name="repNL">
    <xsl:with-param name="pText" select=
    "substring-after($pText, '&#xA;')"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

при применении к следующему документу XML (предоставлен с добавлением cd, чтобы сделать его более интересным):

<catalog>
    <cd>
        <title>Line1
        Line2
        Line3
        </title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Empire
        Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
    <cd>
        <title>Hide your heart</title>
        <artist>Bonnie Tyler</artist>
        <country>UK</country>
        <company>CBS Records</company>
        <price>9.90</price>
        <year>1988</year>
    </cd>
    <cd>
        <title>Greatest Hits</title>
        <artist>Dolly Parton</artist>
        <country>USA</country>
        <company>RCA</company>
        <price>9.90</price>
        <year>1982</year>
    </cd>
</catalog>

желаемый, правильный результат выдается :

<catalog>
   <cd>
      <title>Line1<br/>     Line2<br/>      Line3<br/>      
      </title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Empire<br/>        Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>Columbia</company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
   <cd>
      <title>Hide your heart</title>
      <artist>Bonnie Tyler</artist>
      <country>UK</country>
      <company>CBS Records</company>
      <price>9.90</price>
      <year>1988</year>
   </cd>
   <cd>
      <title>Greatest Hits</title>
      <artist>Dolly Parton</artist>
      <country>USA</country>
      <company>RCA</company>
      <price>9.90</price>
      <year>1982</year>
   </cd>
</catalog>

Объяснение :

  1. Правило идентификации / копии шаблоновкаждый узел "как есть".

  2. Переопределяющий шаблон, соответствующий любому текстовому узлу (также называемому "repNL"), выполняет следующую обработку:

  3. Используя страж (символ NL, добавленный к строке), подстрока перед первым символом NLr (или полная строка, если th символ NL не содержится) копируется в вывод.

  4. Если символ NL действительно содержится, то генерируется элемент br ишаблон вызывает себя рекурсивно для оставшейся строки после этого символа NL.

0 голосов
/ 13 февраля 2015

Если вы используете XslCompiledTransform (C #), я полагаю, что вы столкнетесь с проблемой, если будете использовать ниже API для преобразования XML:XslCompiledTransform.Transform(XmlReader input, XmlWriter results)

Однако ниже API работает хорошо:XslCompiledTransform.Transform(string, string);Это зашито, но я не понимаю, почему ...

...