如何相对于TABLE-PATH SAS XML MAPS

时间:2017-07-11 09:21:13

标签: xml xpath xsd sas

我想将XML文件读入某些SAS数据集。 SAS XML映射使用X-Path(版本1)来引用XML中应该生成行的元素以及其他X-Paht表达式,以引用包含列值的元素或属性。不幸的是,我检索的值并不总是与我需要的行相关联。

简单示例:放在一边

从这个xml

<?xml version="1.0" encoding="iso-8859-1" ?>
<street>
    <house>
        <houseNumber>1</houseNumber>
        <resident>Albert</resident>
        <pet>dog</pet>
    </house>
    <house>
        <houseNumber>2</houseNumber>
        <resident>Bea</resident>
        <resident>Clemance</resident>
    </house>
    <house>
        <houseNumber>3</houseNumber>
        <!--remark: for sale-->
    </house>
    <house>
        <houseNumber>4</houseNumber>
        <resident>Dave</resident>
        <resident>Eve</resident>
        <pet>Cat</pet>
    </house>
</street>

我想提取这些数据

Obs    houseNumber    name      pet
1              1    Albert      dog
2              2    Bea              
3              2    Clemance    
4              4    Dave        cat
5              4    Eve         cat

但是使用这张地图

<?xml version="1.0" encoding="UTF-8"?>

<SXLEMAP name="AUTO_GEN" version="2.1">
    <NAMESPACES count="0"/>
    <TABLE description="residents" name="resident">
        <TABLE-PATH syntax="XPath">resident</TABLE-PATH>
        <COLUMN name="houseNumber" retain="YES"> 
            <PATH syntax="XPath">houseNumber</PATH>
            <TYPE>numeric</TYPE>
            <DATATYPE>integer</DATATYPE>
        </COLUMN>
        <COLUMN name="name">
            <PATH syntax="XPath">resident</PATH>
            <TYPE>character</TYPE>
            <DATATYPE>string</DATATYPE>
            <LENGTH>32</LENGTH>
        </COLUMN>
        <COLUMN name="pet">
            <PATH syntax="XPath">pet</PATH>
            <TYPE>character</TYPE>
            <DATATYPE>string</DATATYPE>
            <LENGTH>32</LENGTH>
        </COLUMN>
    </TABLE>
</SXLEMAP>

这段代码

filename  SXLELIB 'C:\MyFolder\xml.xml';
filename  SXLEMAP 'C:\MyFolder\map.map';
libname   SXLELIB xmlv2 xmlmap=SXLEMAP access=READONLY;

proc print data=SXLELIB.resident(obs=100); 
run;

我明白了:

Obs    houseNumber  name        pet
1              1    Albert      
2              2    Bea         bird
3              2    Clemance    
4              4    Dave        
5              4    Eve              

_这是一个简单的例子,乔在2017年7月12日优雅地解决了。 但是,他的解决方案对我的现实生活问题不起作用,因此我提供了一个

更复杂的例子:异构名称

从这个xml

<?xml version="1.0" encoding="iso-8859-1" ?>
<street>
    <house>
        <houseNumber>1</houseNumber>
        <adult>
            <name>Albert</name>
            <age>41</age>
        </adult>
        <child>
            <name>Ken</name>
            <age>1</age>
        </child>
    </house>
    <house>
        <houseNumber>2</houseNumber>
        <adult>
            <name>Bea</name>
            <age>42</age>
        </adult>
        <adult>
            <name>Clemance</name>
            <age>43</age>
        </adult>
    </house>
    <appartment>
        <houseNumber>3</houseNumber>
        <suiteNumber>1</suiteNumber>
        <!--remark: for rent-->
    </appartment>
    <appartment>
        <houseNumber>3</houseNumber>
        <suiteNumber>2</suiteNumber>
        <adult>
            <name>Ivette</name>
            <age>45</age>
        <adult>
        <adult>
            <name>Jacque</name>
            <age>51</age>
        <adult>
        <child>
            <name>Lea</name>
            <age>2</age>
        </child>
        <child>
            <name>Marie</name>
            <age>3</age>
        </child>
    </appartment>
    <appartment>
        <houseNumber>3</houseNumber>
        <suiteNumber>2</suiteNumber>
        <adult>
            <name>Henri</name>
            <age>44</age>
        <adult>
    </appartment>
    <house>
        <houseNumber>4</houseNumber>
        <adult>
            <name>Dave</name>
            <age>46</age>
        </adult>
        <adult>
            <name>Eve</name>
            <age>51</age>
        </adult>
    </house>
    <house>
        <houseNumber>5</houseNumber>
        <adult>
            <name>Francis</name>
            <age>47</age>
        </adult>
        <adult>
            <name>Gertrude</name>
            <age>48</age>
        </adult>
    </house>
    <house>
        <houseNumber>6</houseNumber>
        <!--remark: for sale-->
    </house>
</street>

我想提取

 Obs  name        age number suite
 1    Albert      41    1    .
 2    Ken         1     1    .
 3    Bea         42    2    .
 4    Clemance    43    2    .
 5    Ivette      45    3    2
 6    Jacque      45    3    2
 7    Lea         2     3    2
 8    Marie       3     3    2
 9    Henri       44    3    3
10    Dave        46    4    .
11    Eve         51    4    .
12    Francis     47    5    .
13    Gertrude    48    5    .

使用名称中的相对地址,类似

<TABLE description="relative address from name" name="resident_1">
    <TABLE-PATH syntax="XPath">name</TABLE-PATH>
    <COLUMN name="name">
        <PATH syntax="XPath">.</PATH>
        <TYPE>character</TYPE>
        <DATATYPE>string</DATATYPE>
        <LENGTH>32</LENGTH>
    </COLUMN>
    <COLUMN name="age" retain="YES"> 
        <PATH syntax="XPath">../age</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
    <COLUMN name="number">
        <PATH syntax="XPath">../../number</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
    <COLUMN name="suite">
        <PATH syntax="XPath">../../suiteNumber</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
</TABLE>

但这只会让我失去价值

所以,我尝试了绝对地址

<TABLE description="name based absolute addresses" name="resident_2">
    <TABLE-PATH syntax="XPath">name</TABLE-PATH>
    <COLUMN name="name">
        <PATH syntax="XPath">name</PATH>
        <TYPE>character</TYPE>
        <DATATYPE>string</DATATYPE>
        <LENGTH>32</LENGTH>
    </COLUMN>
    <COLUMN name="age" retain="YES"> 
        <PATH syntax="XPath">age</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
    <COLUMN name="number">
        <PATH syntax="XPath">houseNumber</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
    <COLUMN name="suite">
        <PATH syntax="XPath">suiteNumber</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
</TABLE>

哪个更好,但是我有两个问题

  • 由于价值在使用后被遗忘,我仍然有somme缺失值
  • 随着年龄的到来,名字的年龄被读得太晚,因此向下移动

 Obs  name        age number suite
 1    Albert      .     1    .
 2    Ken         41    .    .
 3    Bea         1     2    .
 4    Clemance    42    .    .
 5    Ivette      43    3    2
 6    Jacque      45    .    .
 7    Lea         45    .    .
 8    Marie       2     .    .
 9    Henri       3     3    3
 10   Dave        44    4    .
 11   Eve         46    .    .
 12   Francis     51    5    .
 13   Gertrude    47    .    .

所以我尝试从age而不是name开始并使用retain选项

<TABLE description="age based absolute addresses" name="resident_3">
    <TABLE-PATH syntax="XPath">age</TABLE-PATH>
    <COLUMN name="name">
        <PATH syntax="XPath">name</PATH>
        <TYPE>character</TYPE>
        <DATATYPE>string</DATATYPE>
        <LENGTH>32</LENGTH>
    </COLUMN>
    <COLUMN name="age" retain="YES"> 
        <PATH syntax="XPath">age</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
    <COLUMN name="number" retain="yes">
        <PATH syntax="XPath">houseNumber</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
    <COLUMN name="suite" retain="yes">
        <PATH syntax="XPath">suiteNumber</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>
</TABLE>

这也是我的两个问题

  • 由于现在保留了套房和套房号码,我将它们拖得太久了
  • 我失去了失踪年龄的人(即雅克)

Obs  name      age number suite
1    Albert    41    1    .
2    Ken       1     1    .
3    Bea       42    2    .
4    Clemance  43    2    .
5    Ivette    45    3    2
6    Lea       2     3    2
7    Marie     3     3    2
8    Henri     44    3    3
9    Dave      46    4    3
10    Eve      51    4    3
11    Francis  47    5    3
12    Gertrude 48    5    3

有没有人有更好的解决方案?

真正的问题:从CRS或FATCA文件中读取地址

我试图徒劳地从我创建的文件中读回地址数据以回读我写入xml文件的地址数据以使用Common Reporting Standard User Guide

报告外国帐户持有人之后提出了我的问题

地址只有一个必填字段ResCountryCode,它首先出现。它们发生在Individual s和Organization s。

1 个答案:

答案 0 :(得分:1)

我认为可能可以在XPath中作为单个表执行此操作,但根据我的经验,SAS支持XPath的父子兄弟元素(您和# 39; d必须用来正确指定这个......是穷人。

更容易导入为两个表并合并。 SAS非常干净地支持它。

使用两个表,一个是&#34;驻留&#34;的自动化。另一个是&#34; pet&#34;的自动化,你可以轻松地做到这一点。

filename  SXLELIB 'C:\temp\test.xml';
filename  SXLEMAP 'C:\temp\test.map';
libname   SXLELIB xmlv2 xmlmap=SXLEMAP access=READONLY;

proc print data=SXLELIB.resident(obs=100); 
run;
proc print data=SXLELIB.pet(obs=100); 
run;

合并house_ordinal,您已完成。

以下是详细信息:

<TABLE description="house" name="pet">
    <TABLE-PATH syntax="XPath">/street/house/pet</TABLE-PATH>

    <COLUMN class="ORDINAL" name="house_ORDINAL">
        <INCREMENT-PATH beginend="BEGIN" syntax="XPath">/street/house</INCREMENT-PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>

    <COLUMN name="houseNumber">
        <PATH syntax="XPath">/street/house/houseNumber</PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>

    <COLUMN name="pet">
        <PATH syntax="XPath">/street/house/pet</PATH>
        <TYPE>character</TYPE>
        <DATATYPE>string</DATATYPE>
        <LENGTH>3</LENGTH>
    </COLUMN>

</TABLE>

<TABLE description="resident" name="resident">
    <TABLE-PATH syntax="XPath">/street/house/resident</TABLE-PATH>

    <COLUMN class="ORDINAL" name="house_ORDINAL">
        <INCREMENT-PATH beginend="BEGIN" syntax="XPath">/street/house</INCREMENT-PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>

    <COLUMN class="ORDINAL" name="resident_ORDINAL">
        <INCREMENT-PATH beginend="BEGIN" syntax="XPath">/street/house/resident</INCREMENT-PATH>
        <TYPE>numeric</TYPE>
        <DATATYPE>integer</DATATYPE>
    </COLUMN>

    <COLUMN name="resident">
        <PATH syntax="XPath">/street/house/resident</PATH>
        <TYPE>character</TYPE>
        <DATATYPE>string</DATATYPE>
        <LENGTH>8</LENGTH>
    </COLUMN>

</TABLE>