2016-08-03 29 views
0

Jetzt erzeugen würde, ist es nicht schwer XML-Dateien von PHP mit den XMLWriter wie diesen zu erstellen:PHP Code erzeugen, die XML-Ziel mit XMLWriter

$objWriter->startDocument('1.0', 'UTF-8', 'yes'); 

// Data 
$objWriter->startElement("Relationships"); 
$objWriter->writeAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships"); 

$objWriter->startElement("Relationship"); 
$objWriter->writeAttribute("Id", "rId1"); 
$objWriter->writeAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes"); 
$objWriter->writeAttribute("Target", "../drawings/drawing" . $drawingNum . ".xml"); 
$objWriter->endElement(); // Relationship 

$objWriter->endElement(); // Relationships 

$result = $objWriter->getData(); 

Was aber, wenn ich eine „Vorlage“ XML-Datei bereits (sagen wir abo 30 Zeilen), die ich über PHP erzeugen möchte, mit ein paar Attributen, die hier und da vom PHP-Skript berechnet werden.

Jetzt konnte ich gehen und schreiben startElement, writeAttribute und endElement für abount eine halbe Stunde, oder ich könnte:

1) Erstellen solchen Code autommaticly, einig Programm verwenden, das XML analysiert (Java, C#, PHP, was auch immer), lesen Sie die Tags und Attribute und generieren Sie entsprechenden PHP-Code, der wiederum das ursprüngliche XML generiert. Dies würde viel helfen.

2) abbrechen einfach den <?php Tag mit ?> und Dump der XML direkt, nur <?php echo $value ?> Hinzufügen wo man stdout benötigt, dann einige Tricks verwenden, um das nicht zu schreiben, aber speichern Sie es stattdessen in einem String. Dies wäre akzeptabel, wenn diese Trickserei nicht dazu führen würde, dies in ihr eigenes Skript einzufügen und das Ergebnis über curl zu erhalten.

Also, was denkst du, ist die beste Option zu gehen? Ich brauche das für das Exportieren von Diagrammen mit PHPExcel, viele Dinge, die ich gerade brauche, werden von PHPExcel nicht unterstützt, besonders im Diagrammbereich, also schaue ich mir einfach die gewünschten XML-Dateien an und erzeuge sie selbst.

EDIT:

Das ist mein bisher erzielten Fortschritte bei der Codegenerierung in C#:

private static void doWork(string filename, Func<string, string> onElementStart, Func<string, string> onElementEnd, Func<string, string, string> onAttribute) 
{ 
    using (XmlReader reader = XmlReader.Create("file:///" + filename)) 
    { 
     using (StreamWriter file = new StreamWriter(@"c:\kajacx\other\troll_excel5\output.php")) 
     { 
      // Parse the file and display each of the nodes. 
      while (reader.Read()) 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         file.WriteLine(onElementStart(reader.Name)); 
         break; 
        case XmlNodeType.Attribute: 
         file.WriteLine(onAttribute(reader.Name, reader.Value)); 
         break; 
        case XmlNodeType.EndElement: 
         file.WriteLine(onElementEnd(reader.Name)); 
         break; 
       } 
      } 
     } 
    } 
} 

funktioniert ziemlich gut, außer es Attribute (wie in <tag attrName="attValue" /> analysieren tut, aber immer noch besser als nichts Jeder weiß, wie die Attribute funktionieren:

Antwort

1

Im Gegensatz zu untergeordneten Elementen werden Attribute gleichzeitig geladen, wenn der Elementknoten selbst geladen wird, also wenn reader.NodeType == XmlNodeType.Element können Sie XmlReader.MoveToNextAttribute(), um durch die Attribute verwenden, endlich wieder auf das Element mit XmlReader.MoveToElement() bewegt:

private static void DoWork(XmlReader reader, Action<string> onElementStart, Action<string> onElementEnd, Action<string, string> onAttribute) 
{ 
    while (reader.Read()) 
    { 
     switch (reader.NodeType) 
     { 
      case XmlNodeType.Element: 
       onElementStart(reader.Name); 
       if (reader.HasAttributes) 
       { 
        while (reader.MoveToNextAttribute()) 
        { 
         onAttribute(reader.Name, reader.Value); 
        } 
        // Move the reader back to the element node. 
        reader.MoveToElement(); 
       } 
       if (reader.IsEmptyElement) 
       { 
        // Do something special for empty elements? 
       } 
       break; 
      case XmlNodeType.Attribute: 
       onAttribute(reader.Name, reader.Value); 
       break; 
      case XmlNodeType.EndElement: 
       onElementEnd(reader.Name); 
       break; 
     } 
    } 
} 

private static void doWork(string filename, Func<string, string> onElementStart, Func<string, string> onElementEnd, Func<string, string, string> onAttribute) 
{ 
    using (XmlReader reader = XmlReader.Create("file:///" + filename)) 
    { 
     using (StreamWriter writer = new StreamWriter(@"c:\kajacx\other\troll_excel5\output.php")) 
     { 
      DoWork(reader, writer, onElementEnd, onElementEnd, onAttribute); 
     } 
    } 
} 

private static void DoWork(XmlReader reader, TextWriter writer, Func<string, string> onElementStart, Func<string, string> onElementEnd, Func<string, string, string> onAttribute) 
{ 
    DoWork(reader, 
     (s) => writer.WriteLine(onElementStart(s)), 
     (s) => writer.WriteLine(onElementEnd(s)), 
     (s1, s2) => writer.WriteLine(onAttribute(s1, s2)) 
    ); 
} 

(Hier Refactoring ich Ihren Code ein bisschen Testen zu erleichtern.)