c # — генерирует код PHP, который генерирует целевой XML с помощью XMLWriter

Теперь нетрудно создать XML-файлы из PHP с 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();

Однако, что если у меня уже есть XML-файл «шаблона» (скажем, около 30+ строк), который я хочу сгенерировать с помощью PHP, как здесь, с несколькими атрибутами здесь и там, вычисленными PHP-скриптом.

Теперь я мог пойти и написать startElement, writeAttribute а также endElement за полчаса, или я мог бы:

1) Создайте такой код автоматически, используйте программу, которая анализирует XML (Java, C #, PHP и т. Д.), Читает теги и атрибуты и генерирует соответствующий код PHP, который, в свою очередь, генерирует исходный XML. Это очень поможет.

2) Просто отмените <?php пометить с ?> и дамп XML напрямую, только добавляя <?php echo $value ?> где необходимо, используйте хитрость, чтобы не записывать это в стандартный вывод, а вместо этого хранить в строке. Это было бы приемлемо, если бы эта хитрость не вызывала помещение этого внутри собственного скрипта и получение результата с помощью curl.

Так что, по вашему мнению, лучший вариант? Мне это нужно для экспорта диаграмм с помощью PHPExcel, многие вещи, которые мне нужны, просто не поддерживаются PHPExcel, особенно в области диаграмм, поэтому я просто смотрю на нужные файлы XML и генерирую их сам.

РЕДАКТИРОВАТЬ:

Это мой прогресс в создании кода на 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;
}
}
}
}
}

Работает довольно хорошо, за исключением того, что не разбирает атрибуты (как в <tag attrName="attValue" />, но все же лучше, чем ничего. Кто-нибудь знает, как заставить работать атрибуты?

0

Решение

В отличие от дочерних элементов, атрибуты загружаются одновременно с загрузкой самого узла элемента. Таким образом, когда reader.NodeType == XmlNodeType.Element, ты можешь использовать XmlReader.MoveToNextAttribute() циклически перебирать атрибуты, наконец, возвращаясь к элементу с XmlReader.MoveToElement():

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))
);
}

(Здесь я немного переработал ваш код, чтобы облегчить тестирование.)

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]