sas - 修改 SAS XML 映射文件中的数据类型
问题描述
在 SAS 中读取 XML 数据时需要控制数据类型。使用 SAS 中的 XML libname 引擎写入和访问 XML 数据。
XML 文件:
<Test>
<origin>YYYY</origin>
<NumToUse>50503</NumToUse>
<AcctNum>3-219HHJLJ</AcctNum>
<Status>1</Status>
<TADIG>AUSVF</TADIG>
<LocationNumber>1234567891011</LocationNumber>
<Phnumber>1234567890</Phnumber>
<ReferenceNumber>0044E71146</ReferenceNumber>
地图文件:
<COLUMN name="LocationNumber">
<PATH syntax="XPath">/Test/LocationNumber</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>11</LENGTH>
</COLUMN>
<COLUMN name="PhNumber">
<PATH syntax="XPath">/Test/PhNumber</PATH>
<TYPE>character</TYPE>
<DATATYPE>string</DATATYPE>
<LENGTH>15</LENGTH>
</COLUMN>
<COLUMN name="ReferenceNumber">
<PATH syntax="XPath">/Test/ReferenceNumber</PATH>
<TYPE>numeric</TYPE>
<DATATYPE>double</DATATYPE>
</COLUMN>
由于参考编号被视为数字,因此无法获得该特定列的值。它给了我
ERROR: Data contains invalid content for float datatype. Invalid content is 0044E71146
如何将数据读入 SAS 数据集?建议请
解决方案
您可能理解 XMLV2 引擎中内置的自动映射功能选择将 ReferenceNumber 定义为数字而不是字符,因为解析器正在检查的唯一一个值是0044E71146
并且假定#E#
是科学(或指数)表示法一个号码。
解决方案是让 libname 自动映射数据 xml 文件,然后更新映射文件 xml 以满足您的要求。
示例代码:
XMLV2
引擎创建MAPFILE
, 并Proc GROOVY
用于 XML 解析和重写映射文件。
FILENAME XMLFILE "/temp/test.xml" ;
FILENAME MAPFILE "/temp/test.xml.map" ;
* parse data test.xml and write mapfile test.xml.map;
LIBNAME XMLFILE XMLV2 XMLTYPE=XMLMAP XMLMAP=MAPFILE AUTOMAP=REPLACE ;
* parse and rewrite mapfile;
* change desired column nodes to be string/character of a specified length;
proc groovy;
submit "%sysfunc(pathname(mapfile))";
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
* get parameter from submit line;
mapfile=args[0];
* parse mapfile;
doc = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse(
mapfile
)
;
xPath = XPathFactory
.newInstance()
.newXPath()
;
void setCharacter(column,length) {
* find column node and child nodes important to XMLV2 mapfile usage;
node = xPath.evaluate("/SXLEMAP/TABLE/COLUMN[@name='"+column+"']", doc, XPathConstants.NODE);
type = xPath.evaluate("TYPE", node, XPathConstants.NODE);
dtyp = xPath.evaluate("DATATYPE", node, XPathConstants.NODE);
leng = xPath.evaluate("LENGTH", node, XPathConstants.NODE);
if (type != null && !type.getTextContent().equals("character")) { type.setTextContent("character") }
if (dtyp != null && !dtyp.getTextContent().equals("string")) { dtyp.setTextContent("string") }
if (leng == null) {
leng = doc.createElement("LENGTH");
leng.setTextContent(length.toString());
node.appendChild(leng);
}
else
if (!length.getTextContent().equals(length.toString())) {
leng.setTextContent(length.toString());
}
}
// Make sure these two columns will be character, if not already
setCharacter("ReferenceNumber",25);
setCharacter("Phnumber", 20);
// rewrite mapfile with updated nodes
TransformerFactory
.newInstance()
.newTransformer()
.transform(
new DOMSource(doc),
new StreamResult(new File(mapfile))
);
endsubmit;
quit;
* resubmit libname so libref uses now updated mapfile;
LIBNAME XMLFILE XMLV2 XMLTYPE=XMLMAP XMLMAP=MAPFILE;
proc copy in=xmlfile out=work;
run;
注意:您可以对地图文件进行文本解析和重写,但是,地图文件可能无法满足您的“文本解析”期望的可能性很小。
推荐阅读
- clickhouse - 有没有更好的方法来跨 clickhouse 集群查询系统表?
- excel - 结束块 VBA 消息
- entity-framework-core - 为什么 EF Cores CodeFirst 不尊重 HasPrecision?
- reactjs - 如何使用 React Redux Hooks 加载微调器
- javascript - 支持取消和重新启动的 JavaScript 倒数计时器
- laravel - 只修剪视频而不编码 laravel ffmpeg
- java - Java JFrame:Windows 布局和嵌入
- javascript - 带有jwt的标题到带有节点js的另一个页面
- python - 如何在 Python 中计算视频或照片堆栈中事件的相对帧值?
- reactjs - 使用 react-select 和 react refs 时如何获取 ref.current dom 元素?