CDA简介
一、CDA的定义
CDA是一种基于XML的标准,用于描述和交换临床文档。它定义了文档的结构和内容,包括患者信息、诊断结果、治疗计划等。CDA的设计目标是实现文档的可互操作性和可扩展性,使不同的医疗信息系统能够共享和解释这些文档。
二、CDA的作用
1、促进临床信息的共享和交流:CDA提供了一种统一的格式,使不同的医疗信息系统能够共享和交换临床文档。这有助于医生之间的沟通和协作,提高医疗服务的质量和效率。
2、支持电子健康记录的存储和管理:CDA可以用于存储和管理患者的电子健康记录。通过将临床文档结构化,可以方便地检索和分析患者的健康信息,为医生提供决策支持。
3、促进临床研究和数据分析:CDA的结构化格式使得临床数据可以被更好地分析和利用。研究人员可以通过分析大量的CDA文档,发现潜在的疾病模式和治疗效果,推动医学研究的进展。
三、CDA的应用领域
1、医院信息系统:CDA可以用于医院信息系统中的电子病历、检查报告、手术记录等临床文档的存储和交换。
2、健康信息交换:CDA可以用于不同医疗机构之间的健康信息交换,如患者转院、转诊等。
3、临床研究:CDA可以用于临床研究中的数据收集和分析,帮助研究人员发现新的治疗方法和疾病模式。
其实CDA的标准最早是1997年提出来的,慢慢的成为医疗行业的通用标准。
CDA的例子
之前为了讲课,写了下面的这个例子。
国家标准
国家在这方面发布了详细的要求文档。常用的有53个文档,每个文档有几十到一百页。文档可以在官网下载 。而且文档的最后都有数据样例。
CDA的读取和创建
使用了C#代码 进行CDA的读取和创建。
CDA文件的显示、打印和导出
这是导出的PDF
导出的Word文件
CDADOC的代码,整个工程的代码量还是非常多的。下面仅仅一个代码文件。
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Xml;
namespace CDAUtils
{
public class CDADOC
{
public CDANode Data = new CDANode();
public CDADOC()
{
}
public virtual void set_dataset(DataSet ds)
{
set_datatable_文档信息(ds.Tables["文档信息"]);
set_datatable_by_path(ds.Tables["患者角色"], "recordTarget/patientRole");
set_datatable_by_path(ds.Tables["文档创作者"], "author");
set_datatable_by_path(ds.Tables["文档管理机构信息"], "custodian");
set_datatable_by_path(ds.Tables["联系人"], "participant");
}
public virtual DataSet get_dataset()
{
DataSet ds = CDADOC_XSD.get_dataset(this.GetType().Name);
get_datatable_文档信息( ds.Tables["文档信息"] );
get_datatable_by_path(ds.Tables["患者角色"], "recordTarget/patientRole");
get_datatable_by_path(ds.Tables["文档创作者"], "author");
get_datatable_by_path(ds.Tables["文档管理机构信息"], "custodian");
get_datatable_by_path(ds.Tables["联系人"], "participant");
return ds;
}
public void get_datatable_文档信息(DataTable dt)
{
dt.Rows.Clear();
DataRow dr = dt.NewRow();
dr["文档流水号"] = id;
dr["文档机器生成时间"] = effectiveTime;
dr["文档集合编号"] = setId;
dr["文档版本号"] = versionNumber;
dt.Rows.Add(dr);
}
public void set_datatable_文档信息(DataTable dt)
{
if (dt == null)
return;
if (dt.Rows.Count < 1)
{
id = "";
effectiveTime = "";
setId = "";
versionNumber = "";
}
else
{
DataRow dr = dt.Rows[0];
id = Utils.get_str(dr, "文档流水号");
effectiveTime = Utils.get_str(dr, "文档机器生成时间");
setId = Utils.get_str(dr, "文档集合编号");
versionNumber = Utils.get_str(dr, "文档版本号");
}
}
public void get_datatable_by_path(DataTable dt,string path)
{
dt.Rows.Clear();
CDANode node= Data.find_node(path);
if (node!=null)
{
Dictionary<string, string> data = node.get_data();
DataRow dr = dt.NewRow();
foreach (DataColumn dc in dt.Columns)
{
string key = dc.ColumnName;
if (data.ContainsKey(key))
dr[key] = data[key];
}
dt.Rows.Add(dr);
}
}
public void set_datatable_by_path(DataTable dt, string path)
{
if (dt == null)
return;
CDANode node = Data.find_node(path);
if (node != null)
{
if (dt.Rows.Count < 1)
{
node.set_data(Utils.dr2dict_empaty(dt));
return;
}
Dictionary<string, string> data = Utils.dr2dict(dt.Rows[0]);
node.set_data(data);
}
}
public void set_doc_info(string path, string name, string v)
{
CDANode node = Data.find_node(path);
node.set_property(name, v);
}
public string get_doc_info(string path, string name)
{
CDANode node = Data.find_node(path);
return node.get_property(name);
}
public string effectiveTime
{
get
{
return get_doc_info("effectiveTime", "value");
}
set
{
set_doc_info("effectiveTime", "value", value);
}
}
public string id
{
get
{
return get_doc_info("id", "extension");
}
set
{
set_doc_info("id", "extension", value);
}
}
public string setId
{
get
{
return get_doc_info("setId", "text");
}
set
{
set_doc_info("setId", "text", value);
}
}
public string versionNumber
{
get
{
return get_doc_info("versionNumber", "text");
}
set
{
set_doc_info("versionNumber", "text", value);
}
}
public virtual void save(XmlDocument doc)
{
XmlNode ClinicalDocument = doc.SelectSingleNode("/*[name()='ClinicalDocument']");
Data.save_sub_nodes(ClinicalDocument);
}
public void set_patient_data(Dictionary<string, string> data)
{
Data.find_node("recordTarget/patientRole").set_data(data);
}
public void set_patient_provider_data(Dictionary<string, string> data)
{
Data.find_node("recordTarget/patientRole/providerOrganization").set_data(data);
}
public void set_legalAuthenticator_data(Dictionary<string, string> data)
{
Data.find_node("legalAuthenticator").set_data(data);
}
public Dictionary<string, string> get_patient_data()
{
return Data.find_node("recordTarget/patientRole").get_data();
}
public void set_author_data(Dictionary<string, string> data)
{
Data.find_node("author").set_data(data);
}
public Dictionary<string, string> get_author_data()
{
return Data.find_node("author").get_data();
}
public void set_custodian_data(Dictionary<string, string> data)
{
Data.find_node("custodian").set_data(data);
}
public Dictionary<string, string> get_custodian_data()
{
return Data.find_node("custodian").get_data();
}
public void set_participant_data(Dictionary<string, string> data)
{
Data.find_node("participant").set_data(data);
}
public Dictionary<string, string> get_participant_data()
{
return Data.find_node("participant").get_data();
}
public virtual void load(XmlDocument doc)
{
Data.Nodes.Clear();
XmlNode ClinicalDocument = doc.SelectSingleNode("/*[name()='ClinicalDocument']");
foreach (XmlNode node in ClinicalDocument.ChildNodes)
{
string name = node.Name;
switch (name)
{
case "realmCode":
{
Data.Nodes.Add(new CS().load(node));
break;
}
case "typeId":
{
Data.Nodes.Add(new TI().load(node));
break;
}
case "templateId":
{
Data.Nodes.Add(new II().load(node));
break;
}
case "id":
{
Data.Nodes.Add(new II().load(node));
break;
}
case "code":
{
Data.Nodes.Add(new CE().load(node));
break;
}
case "title":
{
Data.Nodes.Add(new ST().load(node));
break;
}
case "effectiveTime":
{
Data.Nodes.Add(new TS().load(node));
break;
}
case "confidentialityCode":
{
Data.Nodes.Add(new CE().load(node));
break;
}
case "languageCode":
{
Data.Nodes.Add(new CS().load(node));
break;
}
case "setId":
{
Data.Nodes.Add(new TXT().load(node));
break;
}
case "versionNumber":
{
Data.Nodes.Add(new TXT().load(node));
break;
}
case "recordTarget":
{
Data.Nodes.Add(new RecordTarget().load(node));
break;
}
case "author":
{
Data.Nodes.Add(new Author().load(node));
break;
}
case "custodian":
{
Data.Nodes.Add(new Custodian().load(node));
break;
}
case "participant":
{
Data.Nodes.Add(new Participant().load(node));
break;
}
case "relatedDocument":
{
Data.Nodes.Add(new RelatedDocument().load(node));
break;
}
case "component":
{
Data.Nodes.Add(new DocComponent().load(node));
break;
}
}
}
}
}
}