2008-11-04 8 views
10

Haftungsausschluss: Folgendes ist eine Sünde gegen XML. Deshalb versuche ich es mit XSLT zu ändern :)Attribut-Whitespace beibehalten

Meine XML sieht derzeit wie folgt aus:

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

Ja, ich bin alle Textdaten in Attribute setzen. Ich hoffe, dass XSLT mich retten kann; Ich möchte zu etwas bewegen:

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

Ich habe tatsächlich all dies habe bisher funktioniert, mit der Ausnahme, dass meine Sünden gegen XML gewesen mehr ... außergewöhnlich. Einige der Tags wie folgt aussehen:

<object description = "This is the first line 

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

ich xsltproc unter Linux verwenden bin, aber es scheint keine Optionen zu haben Leerzeichen zu erhalten. Ich habe versucht, xsl: preserve-space und xml: space = "preserve" vergebens zu verwenden. Jede Option, die ich gefunden habe, scheint zu gelten, Whitespace innerhalb der Elemente selbst zu behalten, aber nicht die Attribute. Jedes einzelne Mal, wird die oben geändert:

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

Die Frage ist also, ich kann das Attribut Leerzeichen bewahren?

+0

Sie sollen Ihre weiß-Räume mit Entitätsverweise für innerhalb des attribe Wertes ersetzen, wie ersetzen '' mit ''. Die Attributwertnormalisierung (3.3.3) hängt dann vom Attributtyp ab, von dem ich denke, dass er "CDATA" defatult ist. Ich denke jedoch, dass Sie es mit ' '>' erzwingen können - kann oder auch nicht korrekt sein. Wenn Sie eine XSL-Datei haben, müssen Sie sicherstellen, dass Sie mit Ihrem White-Space manuell arbeiten. Dies geschieht ähnlich wie bei 'string-join()' und 'tokenize()'. – n611x007

+0

*** Es kann getan werden. *** Sie können ein vollständiges Beispiel ([SSCCE] (http://www.sscce.org/ "Kurz, unabhängig, korrekt (kompilierbar), Beispiel")) aus meine Antwort auf eine andere Frage: http://stackoverflow.com/a/29780972/611007 (Wie ich oben erklärte, ist es nicht die Art, wie Sie es versuchen, aber am Ende wird es funktionieren, wie Sie möchten.) – n611x007

+0

bezogen werden: https://stackoverflow.com/questions/449627/ - bezogen werden: https://stackoverflow.com/questions/2004386/ - bezogen werden: https://stackoverflow.com/questions/1289524/ – n611x007

Antwort

5

Dies ist eigentlich ein rohes XML-Parsing-Problem, etwas, mit dem XSLT Ihnen nicht helfen kann. Ein XML-Pars muss die Zeilenumbrüche in diesem Attributwert in Leerzeichen konvertieren, wie in 3.3.3 "Attributwertnormalisierung" im XML-Standard beschrieben. Alles, was gerade Ihre Beschreibungsattribute liest und die Zeilenumbrüche behält, ist falsch.

Sie können die Zeilenvorschübe möglicherweise wiederherstellen, indem Sie das XML vorverarbeiten, um die Zeilenumbrüche zu umgehen & # 10; Zeichenreferenzen, solange Sie keine Zeilenumbrüche haben, bei denen Charrefs nicht zulässig sind, z. B. innerhalb von Tag-Bodies. Charrefs sollten als Steuerzeichen bis zum Attributwert bestehen, wo sie dann in Textknoten umgewandelt werden können.

+1

Ich bin mir nicht sicher, dass das funktionieren wird. Charrefs werden durch die Bytes ersetzt, die sie durch den XML-Prozessor darstellen, und so wird ein Charref, das sich auf ein Leerzeichen bezieht (wie LINE FEED), als Whitespace normalisiert. – ChuckB

+1

Die Standard und DOM Test Suite sagen, es funktioniert; Deine Implementierung mag variieren, aber die, die ich getestet habe, tun es. – bobince

+0

@ChuckB Ich denke, es kommt darauf an, * ob du deinen xml-Prozessor * steuern kannst. Ich kann eine gute Ausgabe mit einem '.xsl' erstellen, das sowohl in saxon als auch in Firefox funktioniert. – n611x007

3

Gemäß der Annotated XML Spec wird Leerraum in Attributwerten vom XML-Prozessor normalisiert (siehe die (T) Anmerkung zu 3.3.3). Es sieht also so aus, als ob die Antwort wahrscheinlich nein ist.

+0

es sei denn, Sie können Ihren XML-Prozessor steuern. – n611x007

1

Wie andere darauf hingewiesen haben, erlaubt die XML-Spezifikation nicht die Erhaltung von Leerzeichen in Attributen. In der Tat ist dies einer der wenigen Unterscheidungsmerkmale zwischen dem, was Sie mit Attributen und Elementen tun können (der andere ist, dass Elemente andere Tags enthalten können, während Attribute dies nicht können).

Sie müssen die Datei zuerst außerhalb von XML verarbeiten, um die Leerzeichen zu erhalten.

+0

Ich denke, das ist irreführend. Wenn Sie Ihren XML-Prozessor steuern können, scheint es an sich gültig und möglich, diesen Leerraum zu bewahren. Ich könnte das Ergebnis erreichen. – n611x007

0

Wenn Sie Ihren XML-Prozessor steuern können, können Sie es tun.

Aus meiner other answer (die viele Referenzen verknüpft hat):

wenn Sie eine XML wie

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

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

und eine XSL wie

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

Sie eine html erhalten können wie:

<html>guy<br> 
    threep<br> 

</html> 

wie mit einem Prozessor wie diese saxon Befehlszeilen getestet/erzeugt:

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

die 'ATTLIST' und die' DOCTYPE' sind hier eigentlich nicht nötig, CDATA wäre der Standard 'attribute type' für diesen ['AttValue'] (http://www.jelks.nu/XML/xmlebnf.html#NT- AttValue) hier. – n611x007

+0

FYI ein zufälliger Beitrag auf Prozessor vs Parser: http://www.oxygenxml.com/archives/xsl-list/200009/msg00750.html – n611x007

+0

Kredit an [Tomalak] (https://stackoverflow.com/a/2850181/ 611007) für die Vorlage 'string', weil in meinem Ziel-XML-Prozessor ['tokenize'] (http://www.w3.org/TR/xpath-functions/#func-tokenize) nicht verfügbar war. – n611x007