如何正确地将数据从两个SAS数据集导出到一个XML数据文件?
将多个(两个或多个)SAS数据集(dataset1、dataset2)导出到一个XML数据文件并同时引用XMLMap中的不同表的正确方法是什么 执行以下操作时,它可以完美地工作:如何正确地将数据从两个SAS数据集导出到一个XML数据文件?,xml,sas,export,xls,Xml,Sas,Export,Xls,将多个(两个或多个)SAS数据集(dataset1、dataset2)导出到一个XML数据文件并同时引用XMLMap中的不同表的正确方法是什么 执行以下操作时,它可以完美地工作: filename xmlout 'path\to\file\want.xml'; libname xmlout xmlv2 xmltype=xmlmap xmlmap='path\to\file\XMLmap.map'; data xmlout.dim; set work.have_dim; run; 我从另一个S
filename xmlout 'path\to\file\want.xml';
libname xmlout xmlv2 xmltype=xmlmap xmlmap='path\to\file\XMLmap.map';
data xmlout.dim;
set work.have_dim;
run;
我从另一个SAS表中获取数据,并在标题中导出(ID和时间如.map中所示)。
然后,我只需使用以下内容修改.map:
<OUTPUT>
<TABLEREF name="dim" />
<TABLEREF name="header" />
</OUTPUT>
但是,我无法将TABLEREF
添加到标题表中,因为它在文档中指定:TABLEREF=指定要导出的XMLMap中的表的名称。名称在XMLMap定义中必须是唯一的,并且名称必须是有效的SAS名称,最多可以包含32个字符。
(参见)
因此,我的问题是,如果不能使用不同的TABLEREF
,如何将这两个SAS表导出到同一个XML文件中?
在某个时候,我想使用一个数据步骤,在该步骤中,我只需将两个表设置在一起,并且在.map中只使用一个TABLEREF
,如下所示:
data aggregated;
set have_dim have_header;
run;
但是,如何将一些变量重定向到XML输出中的标题
表(ID和时间)和dim
表中的其他变量
所需的XML输出将是:
<?xml version="1.0" encoding="UTF-8"?>
<ns2:message xmlns:ns2="http://www.someurl/common/vo/message" xmlns:ns3="http://www.someurl/common/vo/cube">
<ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:20:47</ns2:time> <!-- the time of the day -->
</ns2:header>
<ns2:content>
<ns2:dataSegment id="OBSERVATION">
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC123" />
<ns3:dim name="VAR" value="VAR1"/>
<ns3:dim name="VALUE" value="Y"/>
<ns3:dim name="DATE" value="2021-01-01T00:00:00" />
</ns3:obs>
</ns2:cube>
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="DEF456" />
<ns3:dim name="VAR" value="VAR2"/>
<ns3:dim name="VALUE" value="N"/>
<ns3:dim name="DATE" value="2021-01-01T00:00:00" />
</ns3:obs>
</ns2:cube>
</ns2:dataSegment>
</ns2:content>
</ns2:message>
用于dim的XML.map
:
<?xml version="1.0" encoding="UTF-8"?>
<!-- ############################################################ -->
<!-- 2021-01-19T08:41:21 -->
<!-- SAS XML Libname Engine Map -->
<!-- Generated by XML Mapper, 904300.0.0.20150204190000_v940m3 -->
<!-- ############################################################ -->
<!-- ### Validation report ### -->
<!-- ############################################################ -->
<!-- XMLMap validation completed successfully. -->
<!-- ############################################################ -->
<SXLEMAP name="AUTO_GEN" version="2.1">
<NAMESPACES count="2">
<NS id="1" prefix="ns2">http://www.someurl/common/vo/message</NS>
<NS id="2" prefix="ns3">http://www.someurl/common/vo/cube</NS>
</NAMESPACES>
<OUTPUT>
<TABLEREF name="dim" />
</OUTPUT>
<!-- ############################################################ -->
<TABLE description="message" name="message">
<TABLE-PATH syntax="XPathENR">/{1}message</TABLE-PATH>
<COLUMN class="ORDINAL" name="message_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
</TABLE>
<!-- ############################################################ -->
<TABLE description="header" name="header">
<TABLE-PATH syntax="XPathENR">/{1}message/{1}header</TABLE-PATH>
<COLUMN class="ORDINAL" name="message_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN class="ORDINAL" name="header_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}header</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
</TABLE>
<!-- ############################################################ -->
<TABLE description="content" name="content">
<TABLE-PATH syntax="XPathENR">/{1}message/{1}content</TABLE-PATH>
<COLUMN class="ORDINAL" name="message_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN class="ORDINAL" name="content_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
</TABLE>
<!-- ############################################################ -->
<TABLE description="dataSegment" name="dataSegment">
<TABLE-PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment</TABLE-PATH>
<COLUMN class="ORDINAL" name="content_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN class="ORDINAL" name="dataSegment_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN name="dataSegment_id">
<PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/@id</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>11</LENGTH>
</COLUMN>
</TABLE>
<!-- ############################################################ -->
<TABLE description="cube" name="cube">
<TABLE-PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube</TABLE-PATH>
<COLUMN class="ORDINAL" name="dataSegment_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN class="ORDINAL" name="cube_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN name="cube_id">
<PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/@id</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>27</LENGTH>
</COLUMN>
</TABLE>
<!-- ############################################################ -->
<TABLE description="obs" name="obs">
<TABLE-PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs</TABLE-PATH>
<COLUMN class="ORDINAL" name="cube_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN class="ORDINAL" name="obs_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
</TABLE>
<!-- ############################################################ -->
<TABLE description="dim" name="dim">
<TABLE-PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs/{2}dim</TABLE-PATH>
<COLUMN class="ORDINAL" name="obs_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN class="ORDINAL" name="dim_ORDINAL">
<INCREMENT-PATH beginend="BEGIN" syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs/{2}dim</INCREMENT-PATH>
<TYPE>numeric</TYPE>
<DATATYPE>integer</DATATYPE>
</COLUMN>
<COLUMN name="CODE">
<PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs/{2}dim/CODE</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>8</LENGTH>
</COLUMN>
<COLUMN name="VAR">
<PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs/{2}dim/VAR1</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>8</LENGTH>
</COLUMN>
<COLUMN name="VALUE">
<PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs/{2}dim/VALUE</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>1</LENGTH>
</COLUMN>
<COLUMN name="DATE">
<PATH syntax="XPathENR">/{1}message/{1}content/{1}dataSegment/{1}cube/{2}obs/{2}dim/DATE</PATH>
<TYPE>numeric</TYPE>
<DATATYPE>datetime</DATATYPE>
<FORMAT width="10">IS8601DA</FORMAT>
<INFORMAT width="10">IS8601DA</INFORMAT>
</COLUMN>
</TABLE>
</SXLEMAP>
dim的XML输出
(dim.XML):
头的XML输出(header.XML):
1234
2021-01-19T09:39:44
所需的最终XML输出:
<?xml version="1.0" encoding="UTF-8"?>
<ns2:message xmlns:ns2="http://www.someurl/common/vo/message" xmlns:ns3="http://www.someurl/common/vo/cube">
<ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:20:47</ns2:time> <!-- the time of the day -->
</ns2:header>
<ns2:content>
<ns2:dataSegment id="OBSERVATION">
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC1" />
<ns3:dim name="VAR" value="VAR1"/>
<ns3:dim name="VALUE" value="Y"/>
<ns3:dim name="DATE" value="2020-12-31T00:00:00" />
</ns3:obs>
</ns2:cube>
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC2" />
<ns3:dim name="VAR" value="VAR2"/>
<ns3:dim name="VALUE" value="N"/>
<ns3:dim name="DATE" value="2020-12-31T00:00:00" />
</ns3:obs>
</ns2:cube>
</ns2:dataSegment>
</ns2:content>
</ns2:message>
<?xml version="1.0" encoding="UTF-8"?><ns2:message xmlns:ns2="http://www.someurl/common/vo/message"><ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:39:44</ns2:time>
</ns2:header></ns2:message>
1234
2021-01-19T09:20:47
将proc xls与冻糕的脚本一起使用时的结果。xls:
<?xml version="1.0" encoding="UTF-8"?>
<ns2:message xmlns:ns2="http://www.someurl/common/vo/message" xmlns:ns3="http://www.someurl/common/vo/cube">
<ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:20:47</ns2:time> <!-- the time of the day -->
</ns2:header>
<ns2:content>
<ns2:dataSegment id="OBSERVATION">
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC1" />
<ns3:dim name="VAR" value="VAR1"/>
<ns3:dim name="VALUE" value="Y"/>
<ns3:dim name="DATE" value="2020-12-31T00:00:00" />
</ns3:obs>
</ns2:cube>
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC2" />
<ns3:dim name="VAR" value="VAR2"/>
<ns3:dim name="VALUE" value="N"/>
<ns3:dim name="DATE" value="2020-12-31T00:00:00" />
</ns3:obs>
</ns2:cube>
</ns2:dataSegment>
</ns2:content>
</ns2:message>
<?xml version="1.0" encoding="UTF-8"?><ns2:message xmlns:ns2="http://www.someurl/common/vo/message"><ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:39:44</ns2:time>
</ns2:header></ns2:message>
1234
2021-01-19T09:39:44
考虑一下,设计用于转换XML文件的特殊用途语言,例如组合来自不同文档的XML文件。SAS可以使用运行XSLT1.0甚至2.0
然而,实际上需要两个XSLT转换,因为所需的输出并不完全是两个XML文件的堆栈,即dim.XML
中的元素被迁移到属性
XSLT 1(另存为.xsl
文件,一个特殊的.xml
文件)
观察
XSLT2(另存为.xsl文件;使用绝对路径引用和文件://
关键字)
SAS(使用宏输出多个文件)
输出
1234
2021-01-19T09:39:44
目标XML需要是什么样子?这两个表是XML的两个物理上独立的部分吗?如果是这样,您可能可以使用XML引擎映射功能创建两个单独的文件,然后将它们缝合在一起。否则,我只会手工编写您自己的数据—编写XML的步骤,而忘记XML引擎。@Tom感谢您的及时回答。我用所需的XML输出编辑了这篇文章。我真的不明白你说“物理上分开的部分”是什么意思,也不知道如何使用data\u null\u
step(s)编写它。我对XML真的是个新手。你将无法从两个不同的文件中执行此操作。您需要将您的数据组合成一种格式,这种格式与您想要导出和导出的格式几乎相同。XML文件是具有特定结构的文本文件。理解基本结构非常简单,您可以使用带有PUT语句的数据步骤重新创建它们,但这意味着也需要手动创建每个标记和ID,因此肯定会很麻烦。如果您更熟悉XML,我会选择数据步骤解决方案,如果您更熟悉SAS,组合数据可能更容易。@Reeza如何“组合”数据以使其与XML输出匹配?对于XML来说,这可能比您想象的要复杂得多。dim.XML
和header.XML
的根都是ns2:message
。脚本和xml输出文件都位于同一文件夹中。但是,使用此特定脚本的proc xsl
似乎没有如编辑的文章中所示工作。忘记提及:在XSLT中,您需要将名称空间(如ns2
)调整为实际名称空间。此外,您所期望的结果不是两个XML的简单堆栈,所以在最终堆栈之前需要进行中间转换。请参阅实质性编辑。非常感谢您使用xsl的解决方案!最后一件事,我怎样才能确保不使用
而使用
?我确实在脚本1.xsl
中将
更改为
,但我不确定这样做是否正确。这里也调整了。如果没有错误并且达到了预期的结果,那么这就是正确的做法!在XSLT中,可以添加带有
的元素和带有
的属性,或者直接添加
和
。继续玩脚本,也许你会像我一样喜欢这种语言!
<?xml version="1.0" encoding="UTF-8"?>
<!--
SAS XML Libname Engine (SAS92XML)
SAS XMLMap Generated Output
Version 9.04.01M3P06242015
Created 2021-01-19T09:39:44
-->
<ns2:message xmlns:ns2="http://www.someurl/common/vo/message">
<ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:39:44</ns2:time>
</ns2:header>
</ns2:message>
<?xml version="1.0" encoding="UTF-8"?>
<ns2:message xmlns:ns2="http://www.someurl/common/vo/message" xmlns:ns3="http://www.someurl/common/vo/cube">
<ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:20:47</ns2:time> <!-- the time of the day -->
</ns2:header>
<ns2:content>
<ns2:dataSegment id="OBSERVATION">
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC1" />
<ns3:dim name="VAR" value="VAR1"/>
<ns3:dim name="VALUE" value="Y"/>
<ns3:dim name="DATE" value="2020-12-31T00:00:00" />
</ns3:obs>
</ns2:cube>
<ns2:cube id="ID_CODE">
<ns3:obs>
<ns3:dim name="CODE" value="ABC2" />
<ns3:dim name="VAR" value="VAR2"/>
<ns3:dim name="VALUE" value="N"/>
<ns3:dim name="DATE" value="2020-12-31T00:00:00" />
</ns3:obs>
</ns2:cube>
</ns2:dataSegment>
</ns2:content>
</ns2:message>
<?xml version="1.0" encoding="UTF-8"?><ns2:message xmlns:ns2="http://www.someurl/common/vo/message"><ns2:header>
<ns2:ID>1234</ns2:ID>
<ns2:time>2021-01-19T09:39:44</ns2:time>
</ns2:header></ns2:message>
*** OUTPUT INDIVIDUAL XML FILES;
%macro output_xmls(dset);
filename xmlout "path\to\file\&dset..xml";
libname xmlout xmlv2 xmltype=xmlmap xmlmap='path\to\file\XMLmap.map';
data xmlout.&dset;
set work.&dset;
run;
libname xmlout clear;
%mend output_xmls;
%output_xmls(header);
%output_xmls(dim);
*** TRANSFORM RAW dim.xml;
proc xsl
in = "path\to\file\dim.xml"
xsl = "path\to\file\script_1.xsl"
out = "path\to\file\new_dim.xml";
run;
*** COMBINE header.xml and new_dim.xml FILES;
proc xsl
in = "path\to\file\header.xml"
xsl = "path\to\file\script_2.xsl"
out = "path\to\file\final.xml";
run;