我的工作有大量的xml配置文件,一个在节点中调用的标记。
示例:
<root>
<pages>
<page>
<file_input_folder>\\Trucks\_MANUAL</file_input_folder>
<file_input_virtual_dir>MANUAL</file_input_virtual_dir>
<file_output_folder>C:\MANUAL</file_output_folder>
<fields>
<field>InvoiceNumber</field>
<field>CustomerNumber</field>
</fields>
</page>
<page>
<file_input_folder>\\Trucks\_MANUAL</file_input_folder>
<file_input_virtual_dir>MANUAL</file_input_virtual_dir>
<file_output_folder>C:\Auto</file_output_folder>
<fields>
<field>InvoiceNumber</field>
<field>AutoNumber</field>
</fields>
</page>
</pages>
</root>
我想要的是如下所示,第二页节点中的重复元素将自动从第一页节点加载:
<root>
<pages>
<page>
<file_input_folder>\\Trucks\_MANUAL</file_input_folder>
<file_input_virtual_dir>MANUAL</file_input_virtual_dir>
<file_output_folder>C:\MANUAL</file_output_folder>
<fields>
<field>InvoiceNumber</field>
<field>CustomerNumber</field>
</fields>
</page>
<page>
<file_output_folder>C:\Auto</file_output_folder>
<fields>
<field>AutoNumber</field>
</fields>
</page>
</pages>
</root>
我的xml文件非常大,如果上面的话可以完成近2k linem,它可以缩小到几百行。
我的环境是php,但欢迎任何语言,例如python和.net。
提前致谢
答案 0 :(得分:0)
第二个例子不起作用,因为很难知道哪些元素被替换(你希望<field>AutoNumber</field>
替换<field>CustomerNumber</field>
但是只留下<field>InvoiceNumber</field>
- 怎么办?)< / p>
这对你的事情来说可能有点过头了,但无论如何都写得很有意思。
我解决它的方法是为任何页面元素使用一个模板,它包含真正常见的数据,然后每个页面都有它拥有的模板额外的数据。
我在每个页面中使用'id'属性来标识您想要哪个页面的值以及用于标识模板的'id'属性。该页面使用(如有必要)“模板”属性来说明它使用的模板。这意味着您可以根据需要使用多个模板。
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
function mergeElement ( $source, &$dest ) {
foreach ( $source as $node ) {
$nodeName = $node->getName();
// If it's a nested item, go down to next level
if ( isset( $dest->$nodeName ) && count($node->children()) > 0) {
mergeElement($node, $dest->$nodeName);
}
else {
$dest->addChild( $nodeName, (string)$node);
}
}
}
function fetchPage ( $pageName, $source ) {
$pageData = $source->xpath ( "//pages/page[@id='{$pageName}']");
// If no page found, exit
if ( count($pageData) == 0 ) {
return false;
}
$pageData = $pageData[0];
unset($pageData['id']);
// If no template - return data as is
if ( !isset($pageData['template'])) {
return $pageData;
}
$template = $source->xpath ( "//template[@id='{$pageData['template']}']")[0];
// Add in page to template
mergeElement ( $template, $pageData );
// remove template id from XML
unset($pageData['template']);
return $pageData;
}
$xml = simplexml_load_file("data.xml");
// Fetch the data for 'pageB'
$page = fetchPage ( "pageB", $xml );
echo $page->asXML();
data.xml包含......
<?xml version="1.0" encoding="UTF-8"?>
<root>
<template id="1">
<file_input_folder>\\Trucks\_MANUAL</file_input_folder>
<file_input_virtual_dir>MANUAL</file_input_virtual_dir>
<fields>
<field>InvoiceNumber</field>
</fields>
</template>
<pages>
<page id="pageA" template="1">
<file_output_folder>C:\MANUAL</file_output_folder>
<fields>
<field>CustomerNumber</field>
</fields>
</page>
<page id="pageB" template="1">
<file_output_folder>C:\Auto</file_output_folder>
<fields>
<field>AutoNumber</field>
</fields>
</page>
<page id="pageC">
<file_output_folder>C:\Auto1</file_output_folder>
<fields>
<field>AutoNumber1</field>
</fields>
</page>
</pages>
</root>
上面显示了模板以及它如何链接到数据页面,最后一页不使用模板并按原样返回。
产生'pageB'的输出(虽然这是格式化的)......
<page>
<file_output_folder>C:\Auto</file_output_folder>
<fields>
<field>AutoNumber</field>
<field>InvoiceNumber</field>
</fields>
<file_input_folder>\\Trucks\_MANUAL</file_input_folder>
<file_input_virtual_dir>MANUAL</file_input_virtual_dir>
</page>