XML数据输出

工作中涉及到XML数据输出,每年报表都会有局部指标的变化,相应的XML节点也会有相应的变更,同时还需能导出往年的数据。这样的要求,需要我们对数据库表的设计的时候采用行设计来。

数据表的设计:

当报表变化增加指标时,只需增加一行数据即可。

XML节点表设计:

输出XML每种报表都有有三个共同特点,,一是取数据,二是取节点,三是数据和节点的组合。代码设计如下

基类:

/**
 * XML数据输出
 * @author Administrator
 *
 * @param <T>
 */
public abstract class GenerateXML<T> {
	
	/**
	 * 获取节点数据
	 * @param paramMap
	 * @return
	 */
	protected abstract List<T> getNodeData(Map<String,Object> paramMap);
	
	/**
	 * 获取节点XML配置
	 * @param paramMap
	 * @return
	 */
	protected abstract List<NodeXMLInfo> getNodeXML(Map<String,Object> paramMap);
	
	/**
	 * 组装节点
	 * @param root
	 * @param paramMap
	 * @return
	 */
	public abstract Element assemblyNode(Element root, Map<String,Object> paramMap, int signNode) throws Exception; 

}

子类:业务类

/**
 * 银行利润表XML
 * @author Administrator
 *
 */
public class BankProfitXML extends GenerateXML<BankProfitInfo> {

	@Override
	protected List<BankProfitInfo> getNodeData(Map<String,Object> paramMap) { 
		return null;
	}

	@Override
	protected List<NodeXMLInfo> getNodeXML(Map<String,Object> paramMap) {
		return null;
	}
	
	@Override
	public Element assemblyNode(Element root, Map<String,Object> paramMap, int signNode) throws Exception{ 		
		List<BankProfitInfo> bpDatas = getNodeData(paramMap);
		List<NodeXMLInfo> nxNodes =  getNodeXML(paramMap);
		Element changeNode = root; 		
			
		for(NodeXMLInfo vNx : nxNodes){//节点	
			//生成节点路径
			String[] nodeSplit = vNx.getXmlPathNode().split("/");				
			for (int i=0; i<nodeSplit.length; i++){
				String nodeName = nodeSplit[i]; 
				if (changeNode.getChild(nodeName) != null) {//节点存在
					changeNode = (Element) changeNode.getContent((changeNode.getChildren().size())-1);
				}else {//创建新节点
					changeNode.addContent(new Element(nodeName));						
				}
			}
			
			//根据具体情况做处理
			//生成末级节点--这里要 根据数据的类型进行相应的转换
			String lastNodeName = vNx.getXmlLastNode();	//末级节点	
			String dataField = vNx.getDataField();		//对应数据字段属性	
			int rowOrder = vNx.getRowOrder();
			Double nodeValue = 0.0;
			for(BankProfitInfo vBp :  bpDatas){//数据
				if(vBp.getRowOrder().intValue()==rowOrder){
					nodeValue = (Double)vBp.getClass().getField(dataField).get(vBp);	
					break;
				}
			} 			
			changeNode.addContent(new Element(lastNodeName).addContent(nodeValue.toString()));
		} 			
			
		return changeNode; 
	}

}

如果存储数据内容采用了列式存储,组合代码变更如下:

	List<BankProfitInfo> bpDatas = getNodeData(paramMap);
	List<NodeXMLInfo> nxNodes =  getNodeXML(paramMap);
	Element changeNode = root;
	Boolean repeatNode;
	for(BankProfitInfo vBp :  bpDatas){//数据
		repeatNode = true;//指定重复节点
		for(NodeXMLInfo vNx : nxNodes){//节点	
			//生成节点路径
			String[] nodeSplit = vNx.getXmlPathNode().split("/");				
			for (int i=0; i<nodeSplit.length; i++){
				String nodeName = nodeSplit[i]; 
				if (changeNode.getChild(nodeName) != null) {//节点存在
					if ((i==signNode)&&(repeatNode==true)){//指定继续生成节点
						changeNode.addContent(new Element(nodeName));
						changeNode = (Element) changeNode.getContent((changeNode.getChildren().size())-1);
						
					}else{//获取节点的子节点
						changeNode = (Element) changeNode.getContent((changeNode.getChildren().size())-1);
					}
				}else {//创建新节点
					changeNode.addContent(new Element(nodeName));						
				}
				if(i==signNode) repeatNode = false;
			}
			
			//生成末级节点--这里要 根据数据的类型进行相应的转换
			String lastNodeName = vNx.getXmlLastNode();	//末级节点	
			String dataField = vNx.getDataField();		//对应数据字段属性				
			Double nodeValue = (Double)vBp.getClass().getField(dataField).get(vBp);				
			changeNode.addContent(new Element(lastNodeName).addContent(nodeValue.toString()));
		} 
	}











### 编写输出 XML 数据的函数 为了实现将数据转换为 XML 格式的功能,可以定义一个 Python 函数 `write_to_xml` 来处理此过程。该函数接受 Pandas DataFrame 和其他必要的参数来构建所需的 XML 结构。 #### 使用 Pandas 的 to_xml 方法 Pandas 提供了内置的支持用于将 DataFrame 转换为 XML 文档。通过设置不同的参数选项,能够灵活地调整输出格式以满足特定需求[^1]。 ```python import pandas as pd from xml.etree.ElementTree import Element, tostring def write_to_xml(df: pd.DataFrame, root_name='root', record_path=None, index=False, mode='w'): """ 将给定的DataFrame保存成XML文件 参数: df (pd.DataFrame): 输入的数据框对象 root_name (str): 输出xml文档根节点名称,默认'root' record_path (str or None): 如果存在嵌套记录,则指定路径;否则设为None index (bool): 是否保留索引列,默认False表示不保留 mode ('w'|'a'): 文件打开模式,'w'-覆盖写入;'a'-追加写入 返回值: str: 表达为字符串形式的目标XML内容 """ # 利用pandas自带方法导出xml并返回其string版本 result_str = df.to_xml( path_or_buffer=None, root_name=root_name, row_name="record", na_rep='', attr_cols=[], elem_cols=None, namespaces={}, prefix=None, encoding='utf-8', xml_declaration=True, pretty_print=True, parser='lxml', stylesheet=None, compression='infer', storage_options=None, index=index, mode=mode) return result_str ``` 上述代码片段展示了如何利用 Pandas 库中的 `to_xml()` 方法创建自定义的 XML 导出工具。这里设置了几个重要参数: - **root_name**: 定义整个 XML 文档最外层标签的名字; - **row_name**: 设置每条记录对应的子元素名; - **index**: 控制是否把原始表格里的行号也一并加入到最终生成的结果里去; - **mode**: 决定了当目标位置已存在同名文件时应采取何种行动——是直接替换还是附加新内容于旧有基础上。 此外,在实际应用过程中可能还需要考虑更多细节配置项,比如命名空间管理、CDATA 区域支持等特性,这些都可以借助官方文档进一步探索和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值