2009-07-16 5 views
2

Wer weiß von einem Perl-Modul, um Text in einem XML-Dokument zu entkommen?Wie kann ich Text für ein XML-Dokument in Perl entkommen lassen?

Ich erzeuge XML, das Text enthalten wird, der vom Benutzer eingegeben wurde. Ich möchte den Text richtig behandeln, damit das resultierende XML gut gebildet wird.

+3

Welche Art von „Flucht“ beziehen Sie sich? –

+1

Versuchen Sie, XML-Ausgabe von Hand zu erstellen? –

Antwort

7

Ich persönlich bevorzuge XML::LibXML - Perl-Bindung für libxml. Eines der Profis - es verwendet eine der schnellsten verfügbaren XML-Verarbeitungsbibliotheken. Hier ist ein Beispiel für die Erstellung von Textknoten:

use XML::LibXML; 
my $doc = XML::LibXML::Document->new('1.0',$some_encoding); 
my $element = $doc->createElement($name); 
$element->appendText($text); 
$xml_fragment = $element->toString(); 
$xml_document = $doc->toString(); 

Und nie, nie XML von Hand erstellen. Es wird schlecht für deine Gesundheit sein, wenn Leute herausfinden, was du getan hast.

+1

Punkt genommen. Ich hätte das XML nicht von Hand erstellen sollen (das waren einfache XML-Dokumente, als ich anfing). Ich muss es schaffen, diese Codezeilen neu zu schreiben. – coldeq

+0

Ich habe diese Antwort nicht für die XML :: LibXML-Empfehlung akzeptiert (ich habe XML :: Writer verwendet), sondern darauf hingewiesen, dass es nicht empfehlenswert ist, XML manuell zu erstellen. – coldeq

+1

Beachten Sie, dass XML :: LibXML Nicht-Perl-Abhängigkeiten aufweist und nicht ohne Weiteres auf Ihrer Plattform installiert werden kann. – muenalan

6

Verwenden Sie XML::Code.

Von CPAN

XML :: Code escape()

Normalerweise jeder Inhalt des Knotens wird beim Rendern entwertet werden (i e.. Sonderzeichen wie '&' wird durch entsprechende Einrichtungen ersetzt werden). Rufen Sie escape() mit Null-Argument, es zu verhindern:

 my $p = XML::Code->('p'); 
     $p->set_text ("—"); 
     $p->escape (0); 
     print $p->code(); # prints <p>&#8212;</p> 
     $p->escape (1); 
     print $p->code(); # prints <p>&amp;#8212;</p> 
3

XML::Entities:

use XML::Entities; 
my $a_encoded = XML::Entities::numify('all', $a); 

Edit: XML :: Entities nur numifies HTML-Entitäten. Verwenden Sie HTML::Entities encode_entities ($ a) stattdessen

+0

XML :: Entities :: numify scheint nur benannte XML-Entitäten in numerische XML-Entitäten zu konvertieren. – coldeq

+0

Sie haben Recht, mein Fehler. Es ist möglich, stattdessen HTML :: Entities und encode_entities zu verwenden. – hovenko

10

Ich bin mir nicht sicher, warum Sie Text, der in einer XML-Datei befindet, müssen. Wenn Ihre Datei enthält:

<foo>x < y</foo> 

Die Datei ist nicht eine XML-Datei trotz der Verbreitung von spitzen Klammern. Eine XML-Datei müssen gültige Daten enthalten, so etwas wie dies bedeutet:

<foo>x &lt; y</foo> 

oder

<foo><![CDATA[x < y]]></foo> 

daher entweder:

  1. Sie bitten nicht um Daten in einer XML-Datei zu entkommen. Stattdessen möchten Sie herausfinden, wie Sie Zeichendaten in eine XML-Datei einfügen, sodass die resultierende Datei gültiges XML ist. oder

  2. Sie haben einige Daten in einer XML-Datei, die für aus einem anderen Grund maskiert werden müssen.

Pflege um zu erarbeiten?

+0

An die Person, die downvoted: Was genau war falsch mit dem, was ich oben gesagt habe? –

+2

Leute werden wütend, wenn Sie sie daran erinnern, dass ihr Pseudo-XML nicht wirklich XML ist. Es ist amüsant ... und traurig. Wie auch immer, ich habe Sie upvoted :) – jrockway

+0

Meine Frage wäre # 1. Ich wusste nicht, dass meine Frage nicht klar war. Ich werde die Frage aktualisieren, um zu klären. – coldeq

1

Nach dem Auschecken von XML :: Code wie von Krish empfohlen, fand ich, dass dies mit der XML :: Code text() Funktion getan werden kann. Zum Beispiel

Übergeben '=' erstellt einen Textknoten, der, wenn gedruckt, keine Tags enthält. Hinweis: dies funktioniert nur für Textdaten. Es wird Attributen nicht korrekt entgehen.

3

Verwenden

XML :: Generator

XML benötigen :: Generator;

mein $ xml = XML :: Generator-> neu (': hübsch', escape => 'immer, apos');

print $ xml-> h1 ("& <> Nicht-HTML Klartext <> &");

, die den gesamten Inhalt innerhalb der Tags ausgedruckt werden (keine Konflikte mit dem Markup).

+0

tolle Sachen bekommen wollen, funktioniert für mich – Gordon

+0

Schöne Schnittstelle, aber zu langsam, wenn Sie Millionen von Zeilen von XML schreiben. – nick

0

Obwohl Sie besser ein Modul wie XML::LibXML oder XML::Code verwenden, können Sie Textdaten in einen CDATA-Abschnitt einbinden. Sie müssen darauf achten nicht nur ]]> in sie zu setzen (diese Sequenz auch außerhalb von CDATA-Abschnitte nicht zulässig ist!):

$text =~ s/\]\]>/]]>]]&gt;<![CDATA[/; 
$text = "<![CDATA[$text]]>"; 
$xml = "<foo>$text</foo>"; 

Als Bonus Code wird mehr Perlish verschleierten aussehen! :-)

6

Der XML :: Simple escape_value könnte auch verwendet werden, aber die Verwendung von XML :: Simple wird nicht für neue Programme empfohlen. Sehen Sie diesen Beitrag 17436965.

Eine manuelle Flucht Post könnte mit regex erfolgen (von escape_value kopiert):

$data =~ s/&/&amp;/sg; 
$data =~ s/</&lt;/sg; 
$data =~ s/>/&gt;/sg; 
$data =~ s/"/&quot;/sg; 
+0

diese naive Implementierung funktioniert normalerweise, aber für Fälle 'a.txt =" a & b "' das wird nicht funktionieren. – zinking

Verwandte Themen