لماذا تقوم وظيفة PROC FCMP دائمًا بإرجاع 33 بايت وليس أكثر؟

StackOverflow https://stackoverflow.com/questions/1032238

  •  06-07-2019
  •  | 
  •  

سؤال

لدي الوظيفة التالية المحددة عبر 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.

إليك خطوة البيانات التي أستخدمها لاختبارها (حيث PageSource.html هو أي ملف html يحتوي على سمات متوافقة مع xhtml - مقتبس بالكامل):

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