我通过PROC FCMP定义了以下功能。代码的要点应该非常明显且相对简单。我从一行XHTML返回一个属性的值。这是代码:

proc fcmp outlib=library.funcs.crawl;
    function getAttr(htmline $, Attribute $) $;

       /*-- Find the position of the match --*/
    Pos = index( htmline , strip( Attribute )||"=" );

       /*-- Now do something about it --*/
       if pos > 0 then do;
          Value = scan( substr( htmline, Pos + length( Attribute ) + 2), 1, '"');
       end;
       else Value = "";
       return( Value);
    endsub;
run;

无论我使用length或attrib语句尝试显式声明返回的数据类型,它总是只返回所请求字符串的最多33个字节,无论实际返回值有多长。无论我正在搜索哪个属性,都会发生这种情况。数据步骤中的相同代码(硬编码)会返回正确的结果,因此这与PROC FCMP有关。

这是我用来测试它的datastep(其中PageSource.html是任何具有xhtml兼容属性的html文件 - 完全引用):

data TEST;
length href $200;
infile "F:\PageSource.html";

input;

htmline = _INFILE_;

href = getAttr( htmline, "href");
x = length(href);

run;

更新:升级到SAS9.2 - 第2版后,这似乎正常工作

有帮助吗?

解决方案 3

我最终退出了使用FCMP定义的数据步骤功能。我不认为他们已准备好迎接黄金时段。我不仅无法解决33字节返回问题,而且还开始经常崩溃SAS。

回到宏观的旧的(几十年前的)技术。这有效:

/*********************************/
/*= Macro to extract Attribute  =*/
/*= from XHTML string           =*/
/*********************************/
%macro getAttr( htmline, Attribute, NewVar );
   if index( &htmline , strip( &Attribute )||"=" ) > 0 then do;
      &NewVar = scan( substr( &htmline, index( &htmline , strip( &Attribute )||"=" ) + length( &Attribute ) + 2), 1, '"' );
   end;
%mend;

其他提示

在这种情况下,输入指针控件应该足够了。希望这有帮助。

/* create a test input file */
data _null_;
  file "f:\pageSource.html";
  input;
  put _infile_;
cards4;
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="w3.org/StyleSheets/TR/W3C-REC.css"; type="text/css"?>
;;;;
run;

/* extract the href attribute value, if any.                          */
/* assuming that the value and the attribute name occurs in one line. */
/* and max length is 200 chars.                                       */
data one;
  infile "f:\pageSource.html" missover;
  input @("href=") href :$200.;
  href = scan(href, 1, '"'); /* unquote */
run;

/* check */
proc print data=one;
run;
/* on lst
Obs                  href
 1
 2     w3.org/StyleSheets/TR/W3C-REC.css
*/

我认为问题(虽然我不知道为什么)是在扫描函数中 - 它似乎是截断来自substr()的输入。如果你将substr函数从scan()中拉出来,将substr函数的结果赋给一个新的变量,然后传递给它进行扫描,它似乎有效。

这是我跑的:

proc fcmp outlib=work.funcs.crawl;
    function getAttr(htmline $, Attribute $) $;
    length y $200;
       /*-- Find the position of the match --*/
    Pos = index( htmline , strip( Attribute )||"=" );

       /*-- Now do something about it --*/
       if pos > 0 then do;
          y=substr( htmline, Pos + length( Attribute ) + 2);
          Value = scan( y, 1, '"');       
       end;
       else Value = "";
       return( Value);
    endsub;
run;

options cmplib=work.funcs;

data TEST;
length href $200;
infile "PageSource.html";

input;

htmline = _INFILE_;
href = getAttr( htmline, "href");
x = length(href);
run;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top