2008-11-04 7 views
10

Avertissement: ce qui suit est un péché contre XML. Voilà pourquoi je suis en train de changer avec XSLT :)Préservation de l'attribut d'espace

Mon XML ressemble actuellement à ceci:

<root> 
    <object name="blarg" property1="shablarg" property2="werg".../> 
    <object name="yetanotherobject" .../> 
</root> 

Oui, je suis en train de toutes les données textuelles dans les attributs. J'espère que XSLT peut me sauver; Je veux aller vers quelque chose comme ceci:

<root> 
    <object> 
     <name>blarg</name> 
     <property1>shablarg</name> 
     ... 
    </object> 
    <object> 
     ... 
    </object> 
</root> 

J'ai en fait eu tout cela de travail jusqu'à présent, à l'exception que mes péchés contre XML ont été plus ... exceptionnelle. Certaines des étiquettes ressemblent à ceci:

<object description = "This is the first line 

This is the third line. That second line full of whitespace is meaningful"/> 

J'utilise xsltproc sous linux, mais il ne semble pas avoir des options pour préserver les espaces. J'ai essayé d'utiliser xsl: preserve-space et xml: space = "preserve" en vain. Chaque option que j'ai trouvée semble s'appliquer à garder les espaces dans les éléments eux-mêmes, mais pas les attributs. Chaque fois, ce qui précède est changée à:

 
This is the first line This is the third line. That second line full of whitespace is meaningful 

La question est, puis-je conserver les espaces blancs d'attributs?

+0

Vous devez remplacer vos-espaces blancs avec des références d'entités à l'intérieur de la valeur attribe, comme remplacer '' avec ''. La normalisation de la valeur de l'attribut (3.3.3) dépend alors du type d'attribut que je pense être 'CDATA' par defatult. Cependant, je pense que vous pouvez le forcer avec '> '- peut ou peut ne pas être correct. Ensuite, si vous avez un XSL vous devez vous assurer de gérer votre espace blanc manuellement, j'ai fait de la même manière que 'string-join()' et 'tokenize()'. – n611x007

+0

*** Il peut être fait. *** Vous pouvez obtenir un exemple complet ([SSCCE] (http://www.sscce.org/ "Short, autoportantes correct (compilable), exemple")) sur ma réponse à une autre question: http://stackoverflow.com/a/29780972/611007 (comme je l'ai expliqué plus haut, ce n'est pas la façon dont vous essayez de le faire, mais à la fin, il fonctionnera comme vous voulez.) – n611x007

+0

connexe: https://stackoverflow.com/questions/449627/ - en relation: https://stackoverflow.com/questions/2004386/ - à l'adresse: https://stackoverflow.com/questions/1289524/ – n611x007

Répondre

5

Il s'agit en fait d'un problème d'analyse XML brute, pas quelque chose que XSLT peut vous aider. Une analyse XML doit convertir les retours à la ligne de cette valeur d'attribut en espaces, conformément à la section «3.3.3 Attribution-Valeur Normalisation» du standard XML. Donc, tout ce qui est en train de lire vos attributs de description et de garder les nouvelles lignes est mal fait.

Vous pouvez récupérer les retours à la ligne en effectuant un pré-traitement du code XML pour échapper les nouvelles lignes à & # 10; les références de caractères, à condition que vous n'ayez pas également de nouvelles lignes où les charrefs ne sont pas autorisés, comme dans les corps de balises. Les charrefs doivent survivre en tant que caractères de contrôle jusqu'à la valeur de l'attribut, où vous pouvez ensuite les transformer en nœuds de texte.

+1

Je ne suis pas sûr que cela fonctionnera. Les charrefs sont remplacés par les octets qu'ils représentent par le processeur XML, et donc un charref se référant à un caractère d'espace (comme LINE FEED) sera normalisé en tant qu'espace. – ChuckB

+1

La suite de tests standard et DOM indique que cela fonctionne; Votre mise en œuvre peut varier, mais celles que j'ai testées le font. – bobince

+0

@ChuckB Je pense que cela dépend * si vous pouvez contrôler votre processeur xml *. Je peux créer une bonne sortie avec un '.xsl' qui fonctionne à la fois dans saxon et firefox. – n611x007

3

Selon le Annotated XML Spec, les espaces blancs dans les valeurs d'attribut sont normalisés par le processeur XML (voir l'annotation (T) au 3.3.3). Donc, il semble que la réponse est probablement non.

+0

sauf vous pouvez contrôler votre processeur xml. – n611x007

1

Comme d'autres l'ont souligné, la spécification XML ne permet pas la préservation des espaces dans les attributs. En fait, c'est l'un des rares facteurs de différenciation entre ce que vous pouvez faire avec les attributs et les éléments (l'autre étant que les éléments peuvent contenir d'autres balises alors que les attributs ne le peuvent pas).

Vous devrez d'abord traiter le fichier en dehors de XML afin de préserver les espaces.

+0

Je pense que c'est trompeur. Si vous pouvez contrôler votre processeur xml, en soi, il semble valide et possible de préserver cet espace blanc. Je pourrais atteindre le résultat. – n611x007

0

Si vous pouvez contrôler votre processeur XML, vous pouvez le faire.

De mon other answer (qui a de nombreuses références liées):

si vous avez un fichier XML comme

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE elemke [ 
<!ATTLIST brush wood CDATA #REQUIRED> 
]> 

<elemke> 
<brush wood="guy&#xA;threep"/> 
</elemke> 

et xsl comme

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template name="split"> 
    <xsl:param name="list"  select="''" /> 
    <xsl:param name="separator" select="'&#xA;'" /> 
    <xsl:if test="not($list = '' or $separator = '')"> 
    <xsl:variable name="head" select="substring-before(concat($list, $separator), $separator)" /> 
    <xsl:variable name="tail" select="substring-after($list, $separator)" /> 

    <xsl:value-of select="$head"/> 
    <br/><xsl:text>&#xA;</xsl:text> 
    <xsl:call-template name="split"> 
     <xsl:with-param name="list"  select="$tail" /> 
     <xsl:with-param name="separator" select="$separator" /> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 


<xsl:template match="brush"> 
    <html> 
    <xsl:call-template name="split"> 
    <xsl:with-param name="list" select="@wood"/> 
    </xsl:call-template> 
    </html> 
</xsl:template> 

</xsl:stylesheet> 

vous pouvez obtenir un html comme:

<html>guy<br> 
    threep<br> 

</html> 

tel que testé/produit avec un processeur comme cette ligne de commande saxon:

java -jar saxon9he.jar -s:in.xml -xsl:in.xsl -o:out.html 
+0

la 'ATTLIST' et' DOCTYPE' ici est en fait inutile, CDATA serait le « type d'attribut » par défaut pour ce [ 'AttValue'] (http://www.jelks.nu/XML/xmlebnf.html#NT- AttValue) ici. – n611x007

+0

FYI un poste aléatoire sur le processeur vs analyseur: http://www.oxygenxml.com/archives/xsl-list/200009/msg00750.html – n611x007

+0

crédit à [Tomalak] (https://stackoverflow.com/a/2850181/ 611007) pour le modèle 'chaîne' car dans mon processeur xml cible ['tokenize'] (http://www.w3.org/TR/xpath-functions/#func-tokenize) n'était pas disponible. – n611x007

Questions connexes