<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Extracting long metadata Textstore (&amp;gt;32K) in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656410#M196813</link>
    <description>Thats good to know:)  I will then  use the function and if the result string is long - and does not include %STPEND then I know it is cut ff, so I will collect the URIs and the use proc metadata just for the "problem" URIs.&lt;BR /&gt;&lt;BR /&gt;I will share the full solution here when finished.   (Its not top priority now, so I wont get a chance to do this in  the next week or so)</description>
    <pubDate>Wed, 10 Jun 2020 13:49:03 GMT</pubDate>
    <dc:creator>DavePrinsloo</dc:creator>
    <dc:date>2020-06-10T13:49:03Z</dc:date>
    <item>
      <title>Extracting long metadata Textstore (&gt;32K)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/654635#M196572</link>
      <description>&lt;P&gt;I need to extract and create text files for each stored process in a metadata path.&amp;nbsp; &amp;nbsp;I got a macro that uses the metadata API - metadata object&amp;nbsp; functions to&amp;nbsp; identify each relevant stored process and extracts the source code from the TextStore metadata object.&amp;nbsp; Unfortunately, some stored processes have more code than fits into the longest possible&amp;nbsp; SAS variable $32767.&amp;nbsp; &amp;nbsp; How can I access the rest of the TextStore object?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Once I identify the TextStore object I have code :&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;length temp_storedtext $32767 ;
objrc=metadata_getattr(&amp;amp;text_uri.,"StoredText",temp_storedtext);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;CODE class=" language-sas"&gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;P&gt;The stored processes have been generated in Enterprise Guide over a number of years by a number of business and power users.&amp;nbsp; &amp;nbsp;&lt;/P&gt;
&lt;P&gt;The macro will have to run on a userid that has read&amp;nbsp; metadata access on all relevant metadata folders.&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It is NOT an option to go into each STP to manually copy the source code.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://communities.sas.com/t5/SAS-Programming/SAS-9-4-Extract-long-texts-from-SAS-Metadata-TextStore/m-p/325785#M72498" target="_blank" rel="noopener"&gt;https://communities.sas.com/t5/SAS-Programming/SAS-9-4-Extract-long-texts-from-SAS-Metadata-TextStore/m-p/325785#M72498&lt;/A&gt;&amp;nbsp;hints at a solution, that the metadata is stored in multiple rows in one of the underlying tables.&amp;nbsp; I would like to know how I could access these tables!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 08 Jun 2020 17:56:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/654635#M196572</guid>
      <dc:creator>DavePrinsloo</dc:creator>
      <dc:date>2020-06-08T17:56:22Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting long metadata Textstore (&gt;32K)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/655776#M196729</link>
      <description>&lt;P&gt;You could use Proc Metadata to pull out the XML and then parse out the text between the &amp;lt;TextStore&amp;gt; tags.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You could also create a .spk from one of the Stored Processes with a lot of code in TextStore, then open the package with 7-zip or the like and inspect the XML if a text store really can contain more than 32KB or if it gets split into multiple ones and you just would need to amend your data step query.&lt;/P&gt;</description>
      <pubDate>Wed, 10 Jun 2020 02:07:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/655776#M196729</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2020-06-10T02:07:23Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting long metadata Textstore (&gt;32K)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656380#M196797</link>
      <description>The TextsStore object in the .spk is indeed one very long string.   &lt;BR /&gt;I will now try with proc metadata and parse the TextStore.&lt;BR /&gt;&lt;BR /&gt;My current code  splits lines on line-feeds and carriage returns and on semicolons which was pretty good for code &amp;lt; 32K.    i.e it splits on '0A'x '0D'x and ';'  which makes for readable code</description>
      <pubDate>Wed, 10 Jun 2020 12:11:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656380#M196797</guid>
      <dc:creator>DavePrinsloo</dc:creator>
      <dc:date>2020-06-10T12:11:09Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting long metadata Textstore (&gt;32K)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656406#M196810</link>
      <description>&lt;P&gt;It always takes me an unreasonable amount of time and try-and-error to get to a request XML which returns a response XML with what I want in it. But I guess you're smarter than I am and especially because you're already able to get the TextStore URI it's eventually no more that hard for you to create "reasonable" XML's which you then can parse to pull out the code.&lt;/P&gt;
&lt;P&gt;Not sure how the code in the response XML will be formatted. May be you're going to have the joy to read it as a data stream (recfm=s)...&lt;/P&gt;</description>
      <pubDate>Wed, 10 Jun 2020 13:46:32 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656406#M196810</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2020-06-10T13:46:32Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting long metadata Textstore (&gt;32K)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656410#M196813</link>
      <description>Thats good to know:)  I will then  use the function and if the result string is long - and does not include %STPEND then I know it is cut ff, so I will collect the URIs and the use proc metadata just for the "problem" URIs.&lt;BR /&gt;&lt;BR /&gt;I will share the full solution here when finished.   (Its not top priority now, so I wont get a chance to do this in  the next week or so)</description>
      <pubDate>Wed, 10 Jun 2020 13:49:03 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/656410#M196813</guid>
      <dc:creator>DavePrinsloo</dc:creator>
      <dc:date>2020-06-10T13:49:03Z</dc:date>
    </item>
    <item>
      <title>Re: Extracting long metadata Textstore (&gt;32K)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/665145#M198822</link>
      <description>&lt;P&gt;Here is the code I promised a couple weeks ago.&amp;nbsp; This macro &lt;CODE class=" language-sas"&gt;get_stpcode_via_xml &lt;/CODE&gt;is called from inside&amp;nbsp; a "fairly" standard another macro which uses metadata functions to find objects&amp;nbsp;using code like&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;metadata_getnobj("omsobj:ClassifierMap?@Id contains '.'",obj_count,obj_uri);
...
rc = metadata_getattr(obj_uri, 'publictype', publictype_nm);
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;and then&amp;nbsp;and restricting parsing to&amp;nbsp;publictype_nm='StoredProcess'&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Macro get_stpcode_via_xml uses proc metadata to extract the source code
*of a stored process for a specific uri and cleans xml escape strings  
* --------------------------------------------------------------------------------*/
%macro get_stpcode_via_xml(text_uri=, out_table=stp_code
         , stp_name=, parent_name=, fullpath_txt=, source_code_outpath=, 
          MetadataUpdated_dttm=);



/* debug: 
%put CALLING: get_stpcode_via_xml(&amp;amp;=text_uri  &amp;amp;=out_table. ;
%put       &amp;amp;=stp_name= &amp;amp;=parent_name ;
%put       &amp;amp;=fullpath_txt ;
%put       &amp;amp;=source_code_outpath;
%put       &amp;amp;=MetadataUpdated_dttm.);*/
filename _in_xml TEMP;
filename _out_xml TEMP;

data _null_;
length string $100;
string=' &amp;lt;TextStore Id="'||"&amp;amp;text_uri."||'"/&amp;gt;';
file _in_xml;
put '&amp;lt;GetMetadata&amp;gt;'
  / ' &amp;lt;Metadata&amp;gt;'
  / string
  / ' &amp;lt;/Metadata&amp;gt;'
  / ' &amp;lt;Ns&amp;gt;SAS&amp;lt;/Ns&amp;gt;'
  / ' &amp;lt;flags&amp;gt;8&amp;lt;/flags&amp;gt;'
  / ' &amp;lt;Options/&amp;gt;'
  / ' &amp;lt;/GetMetadata&amp;gt;'
  /;
run;

proc metadata in=_in_xml out=_out_xml header=none ;
run;

data &amp;amp;out_table.(keep=uri code_txt);
length code_txt $1024;
/* Code lines are in a very long string and separated by &amp;amp;#x0a; */
infile  _out_xml dlmstr='&amp;amp;#x0a;' recfm=V lrecl=16000000 flowover end=eof;
/* output to .sas file */
file stp_file;

retain uri "&amp;amp;text_uri." now ;

input code_txt @@;
%gen_stp_header_text 

if eof and index(code_txt,'TextRole="StoredProcessSourceCode"') then delete;

/* translate tab-marker to blanks */
code_txt=tranwrd(code_txt,'&amp;amp;#x09;','09'x);
code_txt=tranwrd(code_txt,'&amp;amp;amp;','&amp;amp;');
code_txt=tranwrd(code_txt,'&amp;amp;quot;','"');

put code_txt $char.;
run;
filename _in_xml clear;
filename _out_xml clear;
%mend get_stpcode_via_xml;
/* test ...
%get_stpcode_via_xml(text_uri=A5JGVV7O.AG002RRL);


/* The code calls another macro to write some information into the output .sas file using this macro*/
%macro gen_stp_header_text;
if _n_=1 then do;
    now = datetime();
    /* write header */
    put "/* Code for STP: &amp;amp;stp_name.*/";
	put "/* STP Location: &amp;amp;fullpath_txt.*/";
    put "/* MetadataUpdated: &amp;amp;MetadataUpdated_dttm.   Metadata Id : &amp;amp;textstore_uri.*/"; 
	put "/* STP Location: &amp;amp;fullpath_txt.*/";
    put "/* Code Extracted on : " now datetime. " */"; 
    put "/* -------------------------------------------------------------------------*/"; 
    /* find StoredText=*/
    findpos1=index(code_txt,'StoredText');
    /* skip over Stored Text= */
	code_txt=substrn(code_txt,findpos1+12);
end;
%mend gen_stp_header_text;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 25 Jun 2020 20:05:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Extracting-long-metadata-Textstore-gt-32K/m-p/665145#M198822</guid>
      <dc:creator>DavePrinsloo</dc:creator>
      <dc:date>2020-06-25T20:05:22Z</dc:date>
    </item>
  </channel>
</rss>

