2010-09-14 5 views
1

est en dessous du xml qui a section CDATACDATA extrait à l'aide xslt

<?xml version="1.0" encoding="ISO-8859-1"?> 
<character> 
<name> 
<role>Indiana Jones</role> 
<actor>Harrison Ford</actor> 
<part>protagonist</part> 
<![CDATA[ <film>Indiana Jones and the Kingdom of the Crystal Skull</film>]]> 
</name> 
</character> 

Pour xml ci-dessus je dois arracher la CDATA et ajouter un nouvel élément dans l'élément existant « film », de sorte que le résultat final sera :

<?xml version="1.0" encoding="ISO-8859-1"?> 
<character> 
<name> 
<role>Indiana Jones</role> 
<actor>Harrison Ford</actor> 
<part>protagonist</part> 
<film>Indiana Jones and the Kingdom of the Crystal Skull</film> 
<Language>English</Language> 
</name> 
</character> 

Est-ce possible en utilisant XSLT?

+0

D'où provient Anglais dans la sortie? Peut-être que c'était censé faire partie de la contribution? –

Répondre

2

Étant donné que l'élément film dans le bloc CDATA semble être bien formé, vous pouvez utiliser disable-output-escaping. Si vous faites correspondre le nom/text(), sélectionnez value-of avec DOE, puis insérez l'élément Language immédiatement après.

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

<!--Identity template simply copies content forward --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 


<xsl:template match="name/text()"> 
    <!--disable-output-escaping will prevent the "film" element from being escaped. 
    Since it appears to be well-formed you should be safe, but no guarentees --> 
    <xsl:value-of select="." disable-output-escaping="yes" /> 
    <Language>English</Language> 
</xsl:template> 

</xsl:stylesheet> 
+1

+1 Si le DOE est posible et qu'il y a une forte certitude que le CDATA est bien formé –

1

Une autre façon de résoudre ce qui vous donnerait un peu plus de contrôle sur la transformation est d'utiliser Andrew Welsh LexEv XMLReader. Cela vous donne la possibilité de traiter des sections CDATA comme balisage entre autres choses.

+0

+ 1 Solution intéressante. Remarque @Madhu que ce n'est pas une solution XSLT mais fonctionne en fournissant un analyseur XML différent au processeur XSLT. Peut nécessiter un processeur Java XSLT. Si vous avez assez de contrôle sur votre environnement XSLT pour l'utiliser, il s'occupera de vos problèmes d'analyse de manière très complète. – LarsH

0

Tout d'abord, le fait que votre entrée XML ait "CDATA" est dans un sens non pertinent ... le XSLT ne peut pas dire si c'est CDATA ou non. Quelle est la clé de votre entrée XML est que vous avez échappé au balisage <film>...</film>, et vous voulez le transformer en un élément réel.

Si vous savez que l'élément échappé aura toujours un certain nom (« film »), et vous savez où il se produit, vous pouvez enlever et le remplacer facilement:

<xsl:template match="text()[contains(., '&lt;film>')]"> 
     <film> 
     <xsl:value-of select="substring-before(substring-after(., '&lt;film>'), 
       '&lt;/film>')"/> 
     </film> 
    </xsl:template> 

Si vous n » Je ne sais pas à l'avance où les étiquettes échappées se produiront et quels sont les noms des éléments, vous pouvez utiliser <xsl:analyze-string> de XSLT 2.0 pour les trouver et les remplacer. Mais comme l'a souligné Alejandro, l'analyse générale de XML à l'aide d'expressions régulières peut devenir très compliquée. Ce serait seulement possible si vous savez que le balisage sera simple.

+0

+1 un peu plus précis, au cas où il y aurait plusieurs 'nom/texte()'. Bon codage –

+1

défensif plutôt, vous pouvez ajouter

+1

+1 pour la bonne explication. Il faut mentionner que le cas général nécessite une fonction comme saxon: parse() - nous en aurons bientôt un standard dans la prochaine version de F & O. –

3

Une fonction d'identification légèrement modifiée devrait fonctionner.

Compte tenu de cette XML:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<character> 
    <name> 
     <role>Indiana Jones</role> 
     <actor>Harrison Ford</actor> 
     <part>protagonist</part> 
     <![CDATA[ <film>Indiana Jones and the Kingdom of the Crystal Skull</film>]]> 
    </name> 
</character> 

En utilisant cette XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:output method="xml" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*"> 
     <xsl:copy> 
      <xsl:apply-templates select="*" /> 
      <xsl:value-of select="text()" disable-output-escaping="yes"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Produira cette sortie:

<?xml version="1.0" encoding="UTF-8"?> 
<character> 
    <name> 
     <role>Indiana Jones</role> 
     <actor>Harrison Ford</actor> 
     <part>protagonist</part> 
      <film>Indiana Jones and the Kingdom of the Crystal Skull</film> 
    </name> 
</character> 

(Testé avec Saxon-HE 9.3.0.5 dans oXygen 12.2.)

0

Je m'occupais de quelque chose de similaire et j'ai trouvé une bonne solution donc j'ai pensé à le partager avec vous, mais celui-ci est pour NSXMLParser.

Si vous utilisez NSXMLParser il y a une méthode de délégué appelé foundCDATA qui peut ressembler à ceci:

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{ 
    if (!parseElement) { 
     return; 
    } 
    if (parsedElementData==nil) { 
     parsedElementData = [[NSMutableData alloc] init]; 
    } 
    [parsedElementData appendData:CDATABlock]; 

    //Grabs the whole content in CDATABlock. 
    NSMutableString *content = [[NSMutableString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding]; 

} 

ajouter maintenant this prewritten class à votre projet.importer ensuite à la classe d'analyseur que vous voulez l'utiliser dans:

#import NSString_stripHTML

Maintenant, il suffit que vous pouvez ajouter la ligne suivante à foundCDATA méthode:

NSString *strippedContent; 
strippedContent = [content strippedHtml]; 

Maintenant, vous aurez le texte dépouillé sans des caractères supplémentaires. Vous pouvez soustraire ce que vous voulez de ce texte dépouillé.