Manuela: Sonderzeichen in XML

Hi,

ich stehe gerade vor einem ziemlichen Problem.

Ich bekomme aus einer Software heraus XML-Dateien (anders komme ich nicht an die Daten ran)

Diese XML-Dateien sind nun wohl nicht ganz "sauber".

Es stehen Sonderzeichen in den Werten drin, Beispiel:

<name>Name1 " Name2 "</name>

Saxon kann diese nun nicht verarbeiten :-(

Ich kriege diese Meldung:
  Output character not available in this encoding (decimal 65533)
  Transformation failed: Run-time errors were reported

Mein XSL zum wandeln ist sauber. (denk ich)
<xsl:template match="name">~Name~<xsl:value-of select="." />~</xsl:template>

Ich muss die Daten in so ein seltsames FOrmat wandeln, damit ich sie in eine andere Sodtware importieren kann *seufz.

Ich habe 340 XML-Dateien mit insgesamt 320000 Sätzen, die ich nicht täglich manuell nach SOnderzeichen durchsuchen kann.

Gibt es irgendeine Möglichkeit?

Ich muss gestehen, dass ich mit XSL und XML noch nicht sehr viel Erfahrung habe, aber ich das nun leider so brauch. Ich hoffe, meine Frage ist nicht allzu dämlich.

Danke schon mal und Gruß

Manuela

  1. Hellihello Manuela,

    Saxon kenn ich nicht, was ist das?

    Warum nimmst Du nicht erstmal phps simple_xml oder was anderes zum Testen.

    Output character not available in this encoding (decimal 65533)

    Kannst Du bei Saxon die Kodierung einstellen? Warum ist sie nicht utf-8?

    Diese XML-Dateien sind nun wohl nicht ganz "sauber".

    Es stehen Sonderzeichen in den Werten drin, Beispiel:

    <name>Name1 " Name2 "</name>

    Im Textknoten kann eigentlich alles stehen, außer logischerweise "<" (das wäre ja ein neuer Tag) und "&" (das wäre der Beginn einer Entität). Nur diese beiden müssten also mit "&gt;" "&amp;" escaped werden.

    Dank und Gruß,

    frankx

    1. Hallo Frankx,

      danke erst mal für Deine Antwort.

      Saxon ist der Parser, der hier als der BEste empfohlen wird.

      Ich verwendete bisher encoding="ISO-8859-2"

      Das konnte das Hochkomma nicht umsetzen. Mit encoding="ISO-8859-1" ging das dann.
      Aber es gibt ne Menge Sonderzeichen in den Daten :-(

      Jetzt verwende ich encoding="UTF-16"
      Damit geht schon mal sehr sehr viel, aber leider immer noch nicht alles *Haarerauf*

      Ich versuch mal das Zeichen, was er jetzt anmeckert rauszufinden.

      Gruß

      Manuela

      1. Hellihello Manuela,

        Saxon ist der Parser, der hier als der BEste empfohlen wird.

        Wikipedia meint:

        "Saxon ist ein XSL- und XQuery-Prozessor zur Transformation von XML-Dokumenten geschrieben von Michael Kay. Das Programm ist in Java und .NET geschrieben und gilt als sehr schnell. Die aktuelle Version 8.9.0.4 unterstützt XSLT 2.0, XQuery 1.0 und die Empfehlungen für XPath 2.0 vom Januar 2007.

        Das Programm gibt es als kommerzielle Variante Saxon-SA und als Open-Source-Version Saxon-B. Saxon-SA ist im Unterschied zu Saxon-B in der Lage "schema-aware" zu parsen, also eine Integrität der erzeugten Daten zur Laufzeit sicherzustellen."

        Hast Du denn jemals die XML-Funktionen von PHP probiert?

        "SimpleXML (PHP): Die Lightweight-Lösung für PHP, um XML Dokumente einzulesen. Sie ist hoch speichereffizient (besonders im Vergleich zu DOM) und gleichzeitig einfach zu programmieren." (Wikipedia)

        Wie gesagt, außer den beiden erwähnten Sonderzeichen, sollte es keine geben.
        http://www.w3schools.com/xml/xml_cdata.asp

        "There are 5 predefined entity references in XML:
        &lt;  <  less than
        &gt;  >  greater than
        &amp;  &  ampersand
        &apos;  '  apostrophe
        &quot;  "  quotation mark

        Note: Only the characters "<" and "&" are strictly illegal in XML. Apostrophes, quotation marks and greater than signs are legal, but it is a good habit to replace them."

        Das Encoding ist im Kopf der XML-Datei angegeben, wenn nicht, wird utf-8 angenommen. s.a. http://www.w3schools.com/xml/xml_encoding.asp

        Dank und Gruß,

        frankx

        1. @@frankx:

          Wikipedia meint:
          "Saxon ist ein XSL- und XQuery-Prozessor zur Transformation von XML-Dokumenten […]".

          Hast Du denn jemals die XML-Funktionen von PHP probiert?

          Manuela meint:
          "Ich muss die Daten in so ein seltsames FOrmat wandeln"

          Wandeln = transformieren; also XSLT. Was sollte PHP da tun (außer die Transformation anzukurbeln)?

          Live long and prosper,
          Gunnar

          --
          „Das Internet ist ein großer Misthaufen, in dem man allerdings auch kleine Schätze und Perlen finden kann.“ (Joseph Weizenbaum)
          1. Hallo Gunnar,

            genau wandeln muss ich und dabei verzweifel ich noch *kreisch

            Die Dateien sind sehr sehr groß und müssen täglich gewandelt werden für einen Shop.

            In die XML-Dateien kann ich nichts reinschreiben, da es teilweise 10 Minuten dauert sie überhaupt zu öffnen. Ich muss sie also mit XSLT und einem Parser wandeln.

            Aber er steigt halt aus jammer.

            HAst Du ne Idee, was ich da falsch mache?

            Wie gesagt, bin in diesen Dingen (noch) nicht fit.

            Danke auch Dir

            Manuela

          2. Hellihello Gunnar,

            Manuela meint:
            "Ich muss die Daten in so ein seltsames FOrmat wandeln"

            Wandeln = transformieren; also XSLT. Was sollte PHP da tun (außer die Transformation anzukurbeln)?

            Na ich dachte, sie kriegt sie nicht eingelesen.

            1. Einlesen (=error)
            2. Transformieren (geht nur, wenn 1. - soweit kommt sie garnicht)

            Dank und Gruß,

            frankx

        2. Hi Frank,

          ich versteh nix mehr :-(

          Ich habe eine Stelle gefunden, an der der parser aussteigt:

          <category-data category-id="540" category="ISBN">0-7390-3298-4°</category-data>

          Das ° kann er nicht. Aber ich wandle mit UTF-8

          Das mit dem PHP kenn ich gar nicht und ich fürchte, dass ich das so schnell auch nicht schaffe, mich da reinzuarbeiten.

          Irgendeine Idee, warum er an einem popeligen Gradzeichen aussteigt mit dieser Meldung:

          Error reported by XML parser: There is an invalid character in the given encod
          ing. Line 1,
            position 3661483.
          Transformation failed: Run-time errors were reported

          Danke Dir

          Manuela

          1. Hellihello Manuela,

            <category-data category-id="540" category="ISBN">0-7390-3298-4°</category-data>

            Das ° kann er nicht. Aber ich wandle mit UTF-8

            Ich verstehe es so: in Schritt eins parsed Du das XML. Der Parser liest und überprüft auf Korrektheit. Wenn schon hier ein Fehler entsteht, kann er die Transformation garnicht mehr vornehmen.

            Das mit dem Grad-Zeichen hatte ich auch mal. Interessant ist, was 1. im ecoding des XML-Dokumentes steht
            <?xml version="1.0" encoding="???"?>

            und zweitens, was ein Editor mit enstprechendem Encodiung zu der XML-Datei sagt (stellt er das zeichen korrekt dar?).

            Wie liest Du das XML-Dokument ein? Direkt mit Saxon? Schau dir das XML-Dokument doch mal im Editor an.

            Dank und Gruß,

            frankx

  2. Hallo Manuela,

    Ich kriege diese Meldung:
      Output character not available in this encoding (decimal 65533)
      Transformation failed: Run-time errors were reported

    Welche Zeichenkodierung ist für die Ausgabe vereinbart (bei  <xsl:output ... encoding="..."/>)?

    Grüße,
    Thomas

    1. Hallo Thomas,

      ich setze hier jetzt mal meine gesamte XSLT-Datei rein (bitte nicht lachen, hab das erst mal auf die schnelle lernen müssen)

      <xsl:stylesheet version="2.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="text" encoding="UTF-8"/>

      <xsl:template match="nr">~Nr~<xsl:value-of select="." />xsl:text~</xsl:text></xsl:template>
      <xsl:template match="name">~Name~<xsl:value-of select="." />xsl:text~</xsl:text></xsl:template>
      <xsl:template match="price">
      xsl:choose
      <xsl:when test='@country="de"'>~Price~<xsl:value-of select="." />~</xsl:when>
      xsl:otherwise
         xsl:text</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      </xsl:template>

      <xsl:template match="category-data">
      xsl:choose
      <xsl:when test='@category-id="100"'>~Komponist~<xsl:value-of select="." />~</xsl:when>
      <xsl:when test='@category-id="300"'>~Inhalt~<xsl:value-of select="." />xsl:text&#x3C;&#x42;&#x52;&#x2F;&#x3E;~</xsl:text></xsl:when>
      <xsl:when test='@category-id="450"'>~Besetzung~<xsl:value-of select="." />~</xsl:when>
      <xsl:when test='@category-id="1300"'>~Titel~<xsl:value-of select="." />xsl:text~&#xD;</xsl:text></xsl:when>
      xsl:otherwise</xsl:otherwise>
      </xsl:choose>
      </xsl:template>

      <xsl:template match="discount"></xsl:template>
      <xsl:template match="availability"></xsl:template>
      <xsl:template match="supplier-stock"></xsl:template>
      <xsl:template match="tax"></xsl:template>
      <xsl:template match="stock"></xsl:template>
      <xsl:template match="found"></xsl:template>
      <xsl:template match="weight"></xsl:template>

      </xsl:stylesheet>

      mit UTF-8 sind die meisten Dateien ja auch sauber zu parsen, aber das ° macht noch Probs und ein AE (also ein A mit einem E direkt dran)

      HAst Du eine Idee?

      Danke Manu

      1. Hellihello Manuela,

        interssant ist allein die Kodierung des ursprünglichen Dokumentes.

        mit

          
        <?xml version="1.0"?>  
        <xml_root>  
         <xml_child>  
          text_nod°  
         </xml_child>  
        </xml_root>  
        
        

        erhalte ich einen Fehler nur dann, wenn ich oben  - durch die Auslassung des encoding-Attributes - eine Kodierung von utf-8 vorgebe, aber das ° (also das Textdokument) zB. in einem Texeditor mit der Kodierung "unicode (iso-8859-1)" erstellt wurde.

        Fehler:

          
        Warning: Entity: line 4: parser error : Input is not proper UTF-8, indicate encoding ! in D:\xampp\htdocs\PHP_Tests\xml\xml_encoding_specialChars.php on line 8  
          
        Warning:   text_nod° in D:\xampp\htdocs\PHP_Tests\xml\xml_encoding_specialChars.php on line 8  
        
        

        <xsl:stylesheet version="2.0"

        Der Fehler kommt vor dem xsl, oder ist darin das Gradzeichen?

        Dank und Gruß,

        frankx

        1. Hallo Frank,

          ja daran liegt es *freu

          Wenn ich die Dateien erst noch mal mit einem Editor als Unicode speicher, dann klappt es.

          Nun muss ich nur noch einen Weg finden, wie ich das täglich mit 340 Dateien automatisiere *seufz, aber auch das wird mir irgendwie gelingen.

          Danke Dir für Deine Hilfe

          Manuela

          1. Hellihello Manuela,

            ja daran liegt es *freu

            Wenn ich die Dateien erst noch mal mit einem Editor als Unicode speicher, dann klappt es.

            Ja, aber das ist unlogisch. Genau dann sollte es _nicht_ klappen (;-). Der Parser "denkt" dann nämlich, er kriegt "unicode" (iso-8859-1), aber es ist utf-8.

            Zudem sollte bei der Umkodierung im Texteditor das "°" zu einem "°" werden (wenn es vorher utf-8 war).

            Nun muss ich nur noch einen Weg finden, wie ich das täglich mit 340 Dateien automatisiere *seufz, aber auch das wird mir irgendwie gelingen.

            Eigentlich sollte es auch gehen, wenn die xml-Dokumente als  encoding-Attributwert "iso-8859-1" hätten.

            Abgesehen davon, kannst Du textdateien u.a. auch mit PHP umkodieren. Frage ist halt, was sie vorher für eine Kodierung hatten.

            Gruß,

            frankx

            1. Hallo Frank,

              so ganz versteh ich es auch nicht.
              Aber egal, ob ich jetzt was in den Kopf der XML schreibe, oder sie als Unicode speicher, es muss automatisiert passieren.

              PHP kann ich nun überhaupt nicht (es sei denn mein Chef will, dass ich das auch noch lerne). Ich muss es also mit den Sprachen machen, die ich kann ;-) aber da wird es wohl Wege geben, aber nicht mehr heute.

              Danke aber erst mal, DU hast mir ein großes Stück weiter geholfen.

              Manuela

              1. echo $begrüßung;

                so ganz versteh ich es auch nicht.

                Wenn von einer Datei die Kodierung unbekannt ist, gibt es keine technische Lösung, sie zweifelsfrei zu erraten.

                Für XML ist festgelegt, dass die Kodierung bei einer fehlenden encoding-Angabe im XML-Vorspann UTF-8 ist. Wenn das ausgebende Programm die Datei nicht UTF-8-kodiert speichert, oder die verwendete Kodierung nicht im XML-Vorspann angibt, können verarbeitende Programme die Daten nicht selbständig lesen. Du musst dann irgendwie herausfinden, welche Kodierung vorliegt. Am besten durch Fragen des Herstellers. Falls der mit den Schultern zuckt, sollte der sich gefälligst mit der Problematik auseinandersetzen und fehlerfreie Dateien liefern. Wenn der das nicht kann, brauchst du entweder eine Möglichkeit, die beim Lesen zu verwendende Kodierung explizit zu überschreiben (z.B. Kommandozeilenparameter) oder musst die Dateien umkodieren (z.B. iconv). Für beide Varianten musst du aber wissen, welche Kodierung vorliegt. Ein einfacher Test ist, die Datei in einem Browser zu öffnen (möglicherweise die Endung in .txt umbenennen) und im Menü Ansicht->(Zeichen-)Kodierung die Kodierungen durchprobieren. Wenn die Anzeige der Nicht-ASCII-Zeichen dann richtig ist, ist schon mal eine recht hohe Wahrscheinlichkeit gegeben, dass die Datei in der gerade gewählten Kodierung gespeichert ist.

                echo "$verabschiedung $name";

  3. Sofern Problem noch nicht gelöst, kannst du mal eine kurze xml und xsl angeben, bzw. link zum download.

    Bei mir läuft jegliche Transformation, deshalb kann ich nicht ganz nachvollziehen. Allerdings benutze ich Cocoon Umgebung aber ein Saxon8 läuft da auch, mit dem man das mal testen koennte.

    Gruss