InDesign 导出 XML 使用 PHP 解析嵌套列表
InDesign export XML parse nested lists with PHP
我有一个从 InDesign 导出的 XML,我需要将它转换成 HTML。除了项目符号和列表,一切都很简单。 InDesign 导出 XML 如:
<paragraph>First paragraph</paragraph>
<list_level_1>List 1 - Item 1</list_level_1>
<list_level_1>List 1 - Item 2</list_level_1>
<list_level_1>List 1 - Item 3</list_level_1>
<list_level_2>List 1 - Item 3.1</list_level_2>
<list_level_2>List 1 - Item 3.2</list_level_2>
<list_level_1>List 1 - Item 4</list_level_1>
<paragraph>Second paragraph</paragraph>
<list_level_1>List 2 - Item 1</list_level_1>
<list_level_1>List 2 - Item 2</list_level_1>
<paragraph>Third paragraph</paragraph>
我在 PHP5 中手动将 XML 解析为 HTML。之前的片段应该是:
<p>First paragraph</p>
<ol>
<li>List 1 - Item 1</li>
<li>List 1 - Item 2</li>
<li>List 1 - Item 3<ol>
<li>List 1 - Item 3.1</li>
<li>List 1 - Item 3.2</li>
</ol></li>
<li>List 1 - Item 4</li>
</ol>
<p>Second paragraph</p>
<ol>
<li>List 2 - Item 1</li>
<li>List 2 - Item 2</li>
</ol>
<p>Third paragraph</p>
当是简单(一级)列表时,没问题。说到嵌套列表,我就完蛋了。该列表可以用任何 停止,并且所有以前创建的列表都应该正确关闭。
非常欢迎任何建议。
那是我会考虑 XSLT 的地方 ;)
周末我创建了一个解决方案。当然可能有更好的方法,但我不熟悉 XSLT,所以我在纯 PHP 中尝试了它。这是我的解决方案:
preg_match_all('@<Cell>(.*?)</Cell>@', $xml, $cells);
$cells = $cells[1];
function appendLists(&$v) {
global $ol, $ol2, $ul, $ul2, $olc, $ol2c, $ulc, $ul2c;
if (count($ol) > 0 || count($ol2) > 0 || count($ul) > 0 || count($ul2) > 0) {
while (preg_match('@~!ol1-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ol><li>' . join('</li><li>', $ol[$m[1]]) . '</li></ol>', $v);
}
while (preg_match('@~!ul1-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ul><li>' . join('</li><li>', $ul[$m[1]]) . '</li></ul>', $v);
}
while (preg_match('@~!ol2-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ol><li>' . join('</li><li>', $ol2[$m[1]]) . '</li></ol>', $v);
}
while (preg_match('@~!ul2-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ul><li>' . join('</li><li>', $ul2[$m[1]]) . '</li></ul>', $v);
}
$ol = array(); $ol2 = array(); $ul = array(); $ul2 = array();
$olc = -1; $ol2c = -1; $ulc = -1; $ul2c = -1;
}
}
foreach ($cells as $cell) {
$output = '';
if ($cell != '') {
// split to elements
preg_match_all('@<(.*?)>(.*?)</>@u', $cell, $elements);
$ol = array(); $ol2 = array(); $ul = array(); $ul2 = array();
$olc = -1; $ol2c = -1; $ulc = -1; $ul2c = -1;
for ($i = 0; $i < count($elements[0]); $i++) {
$this_element = $elements[1][$i];
$this_value = $elements[2][$i];
$next_element = (isset($elements[1][$i+1]) ? $elements[1][$i+1] : false);
switch ($this_element) {
case 'paragraph':
$output .= '<p>' . $this_value . '</p>';
if ($next_element === 'ord_list1') { $olc++; $ol[$olc] = array(); $output .= "~!ol1-$olc-here!~"; }
elseif ($next_element === 'list1') { $ulc++; $ul[$ulc] = array(); $output .= "~!ul1-$ulc-here!~"; }
elseif ($next_element === 'ord_list2') { $ol2c++; $ol2[$ol2c] = array(); $output .= "~!ol2-$ol2c-here!~"; }
elseif ($next_element === 'list2') { $ul2c++; $ul2[$ul2c] = array(); $output .= "~!ul2-$ul2c-here!~"; }
break;
case 'ord_list1':
if ($output == '') { $olc++; $ol[$olc] = array(); $output .= "~!ol1-$olc-here!~"; }
if ($next_element === 'ord_list2') { $ol2c++; $ol2[$ol2c] = array(); $this_value .= "~!ol2-$ol2c-here!~"; }
elseif ($next_element === 'list2') { $ul2c++; $ul2[$ul2c] = array(); $this_value .= "~!ul2-$ul2c-here!~"; }
$ol[$olc][] = $this_value;
break;
case 'ord_list2':
if ($output == '') $output .= '~!ol2-here!~';
$ol2[$ol2c][] = $this_value;
break;
case 'list1':
if ($output == '') { $ulc++; $ul[$ulc] = array(); $output .= "~!ul1-$ulc-here!~"; }
if ($next_element === 'ord_list2') { $ol2c++; $ol2[$ol2c] = array(); $this_value .= "~!ol2-$ol2c-here!~"; }
elseif ($next_element === 'list2') { $ul2c++; $ul2[$ul2c] = array(); $this_value .= "~!ul2-$ul2c-here!~"; }
$ul[$ulc][] = $this_value;
break;
case 'list2':
if ($output == '') { $ul2c++; $ul2[$ul2c] = array(); $output .= "~!ul2-$ul2c-here!~"; }
$ul2[$ul2c][] = $this_value;
break;
}
}
appendLists($output);
}
}
非常感谢大家对我的问题的关注。
祝你有个愉快的一天。
我有一个从 InDesign 导出的 XML,我需要将它转换成 HTML。除了项目符号和列表,一切都很简单。 InDesign 导出 XML 如:
<paragraph>First paragraph</paragraph>
<list_level_1>List 1 - Item 1</list_level_1>
<list_level_1>List 1 - Item 2</list_level_1>
<list_level_1>List 1 - Item 3</list_level_1>
<list_level_2>List 1 - Item 3.1</list_level_2>
<list_level_2>List 1 - Item 3.2</list_level_2>
<list_level_1>List 1 - Item 4</list_level_1>
<paragraph>Second paragraph</paragraph>
<list_level_1>List 2 - Item 1</list_level_1>
<list_level_1>List 2 - Item 2</list_level_1>
<paragraph>Third paragraph</paragraph>
我在 PHP5 中手动将 XML 解析为 HTML。之前的片段应该是:
<p>First paragraph</p>
<ol>
<li>List 1 - Item 1</li>
<li>List 1 - Item 2</li>
<li>List 1 - Item 3<ol>
<li>List 1 - Item 3.1</li>
<li>List 1 - Item 3.2</li>
</ol></li>
<li>List 1 - Item 4</li>
</ol>
<p>Second paragraph</p>
<ol>
<li>List 2 - Item 1</li>
<li>List 2 - Item 2</li>
</ol>
<p>Third paragraph</p>
当是简单(一级)列表时,没问题。说到嵌套列表,我就完蛋了。该列表可以用任何
非常欢迎任何建议。
那是我会考虑 XSLT 的地方 ;)
周末我创建了一个解决方案。当然可能有更好的方法,但我不熟悉 XSLT,所以我在纯 PHP 中尝试了它。这是我的解决方案:
preg_match_all('@<Cell>(.*?)</Cell>@', $xml, $cells);
$cells = $cells[1];
function appendLists(&$v) {
global $ol, $ol2, $ul, $ul2, $olc, $ol2c, $ulc, $ul2c;
if (count($ol) > 0 || count($ol2) > 0 || count($ul) > 0 || count($ul2) > 0) {
while (preg_match('@~!ol1-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ol><li>' . join('</li><li>', $ol[$m[1]]) . '</li></ol>', $v);
}
while (preg_match('@~!ul1-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ul><li>' . join('</li><li>', $ul[$m[1]]) . '</li></ul>', $v);
}
while (preg_match('@~!ol2-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ol><li>' . join('</li><li>', $ol2[$m[1]]) . '</li></ol>', $v);
}
while (preg_match('@~!ul2-(\d+)-here!~@u', $v, $m)) {
$v = str_replace($m[0], '<ul><li>' . join('</li><li>', $ul2[$m[1]]) . '</li></ul>', $v);
}
$ol = array(); $ol2 = array(); $ul = array(); $ul2 = array();
$olc = -1; $ol2c = -1; $ulc = -1; $ul2c = -1;
}
}
foreach ($cells as $cell) {
$output = '';
if ($cell != '') {
// split to elements
preg_match_all('@<(.*?)>(.*?)</>@u', $cell, $elements);
$ol = array(); $ol2 = array(); $ul = array(); $ul2 = array();
$olc = -1; $ol2c = -1; $ulc = -1; $ul2c = -1;
for ($i = 0; $i < count($elements[0]); $i++) {
$this_element = $elements[1][$i];
$this_value = $elements[2][$i];
$next_element = (isset($elements[1][$i+1]) ? $elements[1][$i+1] : false);
switch ($this_element) {
case 'paragraph':
$output .= '<p>' . $this_value . '</p>';
if ($next_element === 'ord_list1') { $olc++; $ol[$olc] = array(); $output .= "~!ol1-$olc-here!~"; }
elseif ($next_element === 'list1') { $ulc++; $ul[$ulc] = array(); $output .= "~!ul1-$ulc-here!~"; }
elseif ($next_element === 'ord_list2') { $ol2c++; $ol2[$ol2c] = array(); $output .= "~!ol2-$ol2c-here!~"; }
elseif ($next_element === 'list2') { $ul2c++; $ul2[$ul2c] = array(); $output .= "~!ul2-$ul2c-here!~"; }
break;
case 'ord_list1':
if ($output == '') { $olc++; $ol[$olc] = array(); $output .= "~!ol1-$olc-here!~"; }
if ($next_element === 'ord_list2') { $ol2c++; $ol2[$ol2c] = array(); $this_value .= "~!ol2-$ol2c-here!~"; }
elseif ($next_element === 'list2') { $ul2c++; $ul2[$ul2c] = array(); $this_value .= "~!ul2-$ul2c-here!~"; }
$ol[$olc][] = $this_value;
break;
case 'ord_list2':
if ($output == '') $output .= '~!ol2-here!~';
$ol2[$ol2c][] = $this_value;
break;
case 'list1':
if ($output == '') { $ulc++; $ul[$ulc] = array(); $output .= "~!ul1-$ulc-here!~"; }
if ($next_element === 'ord_list2') { $ol2c++; $ol2[$ol2c] = array(); $this_value .= "~!ol2-$ol2c-here!~"; }
elseif ($next_element === 'list2') { $ul2c++; $ul2[$ul2c] = array(); $this_value .= "~!ul2-$ul2c-here!~"; }
$ul[$ulc][] = $this_value;
break;
case 'list2':
if ($output == '') { $ul2c++; $ul2[$ul2c] = array(); $output .= "~!ul2-$ul2c-here!~"; }
$ul2[$ul2c][] = $this_value;
break;
}
}
appendLists($output);
}
}
非常感谢大家对我的问题的关注。 祝你有个愉快的一天。