2011-05-15 5 views
2

J'ai une liste Sharepoint que je veux convertir en JSON via une vue de données XSL.Remplacer le nouveau caractère ligne par <br /> XSL

J'ai une fonction de remplacement récursive XSL que j'utilise pour remplacer tous les caractères spéciaux (barre oblique inverse d'échappement, guillemets doubles à & quot; etc) qui me donne un bon JSON propre qui analyse correctement dans le navigateur des utilisateurs.

La dernière chose dont j'ai besoin pour échapper/remplacer est la nouvelle ligne char. La nouvelle ligne provoque des erreurs dans l'analyse du JSON dans certains navigateurs.

Voici quelques-uns xsl qui teste si le contenu du titre a une nouvelle ligne char, si elle ne nous affichons un paragraphe:

<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> 

Voici quelques-uns échantillon 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> 

" Empire Burlesque "devrait être le seul élément à réussir le test, mais les trois titres passent l'instruction if et sont sortis.

EDIT

Modification de la solution ci-dessous, je suppose que cela devrait fonctionner si je voulais faire la recherche et de remplacement sur une base de nœud individuel? Je ne serai pas en mesure de le tester dans Sharepoint jusqu'à demain.

<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> 
+0

On dirait un double: http://stackoverflow.com/questions/3309746 – mzjn

+0

Impossible de reproduire avec les entrées fournies. Pour l'exemple XML et votre exemple XSLT, il s'agit uniquement du titre "Empire Burlesque". Je n'ai pas tous les trois titres dans la sortie. Êtes-vous sûr que l'exemple XML correspond à vos données réelles? –

+0

Bonne question, +1. Voir ma réponse pour une solution complète, courte et facile et pour une explication détaillée. –

Répondre

2

« Empire Burlesque » devrait être le seul élément de passer le test, mais tous les trois titres passer l'instruction if et sont émis.

Impossible de reproduire le problème allégué - testé avec 9 différents processeurs XSLT, y compris tous de Microsoft.

Quoi qu'il en soit:

Cette transformation remplace tout caractère NL dans un nœud de texte avec un élément 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> 

lorsqu'il est appliqué sur le document XML suivant (celui fourni avec une ajouté cd pour le rendre plus intéressant):

<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> 

le résultat voulu, correct produit:

<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> 

Explication:

  1. La règle d'identité/copie de modèle chaque nœud "en l'état".

  2. Le modèle primordial qui correspond à un nœud de texte (également nommé « repNL ») prforms le traitement suivant:

  3. l'aide d'une sentinelle (un caractère NL ajouté à la chaîne), la sous-chaîne avant le premier NL caractère (ou la chaîne complète, si aucun caractère NL n'est contenu) est copié dans la sortie. Si un caractère NL est réellement contenu, un élément br est généré et le modèle s'appelle récursivement pour la chaîne restante après ce caractère NL.

0

Si vous utilisez XslCompiledTransform (C#), je crois que vous rencontrerez le problème si vous utilisez ci-dessous API pour transformer le XML:
XslCompiledTransform.Transform(XmlReader input, XmlWriter results)

Cependant, au-dessous API fonctionne bien:
XslCompiledTransform.Transform(string, string);
C'est câblé, mais je ne figure pas pourquoi ...

Questions connexes