BookmarkSubscribeRSS Feed
jimbarbour
Meteorite | Level 14

I want to create an Excel spreadsheet with ODS.  I want to create a property with a custom name, MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Name and assign it a value of either "External Label" or "Internal Label".  This is a company specific requirement that we specify the sensitivity of all documents.

 

I know how to create the standard properties like Author, Comments, etc that go into the core.xml part of an xlsx file, but I don't know how to create a custom property name that would go into the custom.xml part of an xlsx file.  The screen print below is of the docProps folder within an xlsx file that has had the custom property manually set.  The XML below that is the contents of custom.xml.

 

I've Googled some, but everything I'm finding relates to just standard properties like Author.  Can anyone point me in the right direction here?

 

Jim

 

jimbarbour_0-1667514268775.png

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<Properties xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties">
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Enabled" pid="2" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>true</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_SetDate" pid="3" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>2022-11-02T22:36:32Z</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Method" pid="4" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>Privileged</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Name" pid="5" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>External Label</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_SiteId" pid="6" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>db05faca-c82a-4b9d-b9c5-0f64b6755421</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_ActionId" pid="7" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>006e8ed9-6489-4393-a145-7272eed3aa2d</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_ContentBits" pid="8" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>0</vt:lpwstr>
</property>
</Properties>
22 REPLIES 22
Kurt_Bremser
Super User

I think you will have to first disassemble the .xlsx file (after creation with ODS), then add the text to the custom.xml file, and then reassemble the .xlsx.

jimbarbour
Meteorite | Level 14

Hello, Kurt,

 

That's along the lines of what I was thinking, that I'd have to create the XML with a Data step and add it to the xlsx file inside the docProps folder.  It shouldn't be too hard, but I was hoping that there was something that SAS already had in place.

 

I wonder if @Cynthia_sas might have any insight here.

 

Jim

ballardw
Super User

You don't mention how you are creating the Excel file so I'm not sure this is at all helpful.

The ODS EXCEL option CATEGORY='text' will place stuff into the Custom Properties of the file. I just can't see how to set the name, it seems to get a generic category tag as the name and the text string is the value.

Might be helpful as you could have the string value in place in the properties and be able to reduce the amount of editing needed.

jimbarbour
Meteorite | Level 14

Hi, @ballardw 

 

Sorry.  I should have said more about how I'm creating the Excel spreadsheet.  I'm using ODS Excel.  Here's a simple example, below.  I tried setting Text= in the ODS Excel options, but I didn't see where it set anything after it ran.  I may be doing it wrong (syntax or something); I've not used this feature heretofore.  It ran successfully but I didn't see any parameter set in the Custom Properties when I examined the resultant xlsx file, and I didn't see a custom.xml file inside the docProps folder inside the xlsx file.

 

Jim

 

DATA	WORK.Test_Data;
	INFILE	DATALINES4 	DSD	DLM='09'X  missover;
	INPUT	Animal 		$
			Legs		
			Best_Sense	$
			;
DATALINES4;
Dog	4	Smell
Eagle	2	Sight
Bear	4	Smell
Rabbit	4	Hearing 
;;;;
RUN;

ODS	EXCEL	FILE	=	"&File_Name"
	AUTHOR			=	'Jim Barbour via SAS'
	CATEGORY		=	"Iteration &Iteration"
	COMMENTS		=	'This is a test to set the sensitivity to External'
/*	TEXT			=	"MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Name	=	""External Label"""	*/
	;

PROC	PRINT	DATA=	Test_Data;
RUN;

ODS EXCEL CLOSE;
ballardw
Super User

Maybe a configuration issue. How did you check on the properties?

When I open the file in Libre Office (I don't have Microsoft Office programs installed on this machine) and open the Properties from the File>Properties menu I get the following. The "property name" bit is the result of trying a number of ways that might have "tricked" the app into setting a desired property name but no joy.

customproperty.png

jimbarbour
Meteorite | Level 14

@ballardw ,

 

I check by:

a) looking at the info panel of Excel and then opening up the drop down for "advanced properties" and

b) looking at the xml files embedded inside the xlsx file

 

Setting "Text=xxxx" does work... sort of.  It doesn't affect the custom properties though.  Text= just puts a line of inside your Excel worksheet.  The below program produces the screen printed output, below.  Note the value in cell A1.

 

Jim

 

jimbarbour_0-1667606862720.png

ODS	EXCEL	FILE		=	"&File_Name"
	TITLE				=	'Animal Senses and Locomotion'
	AUTHOR				=	'Jim Barbour via SAS'
	CATEGORY			=	"Iteration &Iteration"
	COMMENTS			=	'This is an attempt to set the sensitivity to External Label'
	STATUS				=	'Test'
	KEYWORDS			=	'Custom Properties'
	OPTIONS(
		SHEET_NAME		=	'Animal_Senses_Locomotion'
		GRIDLINES		=	'ON'
		TAB_COLOR		=	'YELLOW'
		)
	TEXT				=	"Hello Ballard, this is text"
	;

PROC	PRINT	DATA=	Test_Data;
RUN;

ODS EXCEL CLOSE;
Tom
Super User Tom
Super User

It does not look like SAS creates that XML file.  At least PROC EXPORT does not.

So just add it.

%let filename=~/class.xlsx;
proc export data=sashelp.class file="&filename" replace dbms=xlsx;
run;
data _null_;
  file "&filename" zip member="docProps/custom.xml";
  infile cards truncover;
  input line $char200.;
  len=length(line);
  put line $varying200. len ;
cards4;
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<Properties xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties">
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Enabled" pid="2" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>true</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_SetDate" pid="3" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>2022-11-02T22:36:32Z</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Method" pid="4" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>Privileged</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Name" pid="5" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>External Label</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_SiteId" pid="6" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>db05faca-c82a-4b9d-b9c5-0f64b6755421</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_ActionId" pid="7" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>006e8ed9-6489-4393-a145-7272eed3aa2d</vt:lpwstr>
</property>
-<property name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_ContentBits" pid="8" fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}">
<vt:lpwstr>0</vt:lpwstr>
</property>
</Properties>
;;;;
jimbarbour
Meteorite | Level 14

@Tom ,

 

Thank you!  This is excellent.  

 

Now, I've discovered another complication.  The .rels file and the [Content_Types].xml files have to be updated to include the fact that a custom.xml now exists.  However, when I try to read in the .rels file which is in the _rels folder, SAS says that it can't find the file.  I'm suspicious that the period in the .rels file may be throwing SAS off, but I'm not sure.  If I use the same code to try to read a different file in the very same xlsx, it works just fine.  Code is below.  Log is below that.  

 

Do you have any idea what's going on here?  

 

Jim

 

File is clearly present inside the _rels folder inside the xlsx file:

jimbarbour_0-1667607656097.png

 

data	WORK.Rels_XML;
	DROP	_:;
	infile	"&File_Name"	zip	member="_rels&Slash..rels"	LENGTH=SAS_Length;
*	infile	"&File_Name"	zip	member="docProps&Slash.custom.xml"	LENGTH=SAS_Length;
	INPUT	Line	$VARYING32767.	SAS_Length;
	_Position	=	FIND(Line, '</relationships>', 'i');
	IF	_Position	THEN
		DO;
			SUBSTR(Line,_Position)	=	'<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>';
		END;
run;

ERROR: Entry _rels\.rels in zip file 
       C:\Users\jbarbou6\Documents\SAS\Pgm\Training\Excel_Properties_ODS\Excel_External_Label_6.xlsx does not exist.
ERROR: Physical file does not exist, _rels\.rels.

 

Tom
Super User Tom
Super User

What are you trying to read it with?

Works file for me just using a data step.

132  data _null_;
133    infile "&fname" zip member="_rels/.rels" ;
134    input;
135    put _infile_;
136  run;

NOTE: The infile "xxx/class.xlsx" is:
      (system-specific pathname),
      (system-specific file attributes)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
   <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
   <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
   <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
</Relationships>
NOTE: 6 records were read from the infile (system-specific pathname).
      The minimum record length was 16.
      The maximum record length was 149.
NOTE: DATA statement used (Total process time):
      real time           0.09 seconds
      cpu time            0.00 seconds
jimbarbour
Meteorite | Level 14

@Tom, I'm reading the xlsx file with the Data step I posted earlier.  I'll post it below for ease of reference.

 

Jim

data	WORK.Rels_XML;
	DROP	_:;
	infile	"&File_Name"	zip	member="_rels&Slash..rels"	LENGTH=SAS_Length;
*	infile	"&File_Name"	zip	member="docProps&Slash.custom.xml"	LENGTH=SAS_Length;
	INPUT	Line	$VARYING32767.	SAS_Length;
	_Position	=	FIND(Line, '</relationships>', 'i');
	IF	_Position	THEN
		DO;
			SUBSTR(Line,_Position)	=	'<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>';
		END;
run;
Tom
Super User Tom
Super User

Why did you use \ instead of / in the member name?

jimbarbour
Meteorite | Level 14

@Tom, I'm running on a Windows 2016 server.  Normally paths use a back slash on Windows.  Maybe it should be a forward slash inside a zip archive?  That would be counterintuitive that they would not follow the OS, but I suppose it's worth a try.  I it will try later today when I get a chance.

 

Jim

Tom
Super User Tom
Super User

You can ask SAS to lookup the names.

ods excel file='c:\downloads\class.xlsx' ;
proc print data=sashelp.class;
run;
ods excel;
filename xlsx zip 'c:\downloads\class.xlsx' ;

data xlsx_members ;
  did = dopen('xlsx');
  do num=1 to dnum(did);
    length name $200;
    name = dread(did,num);
    output;
  end;
  did=dclose(did);
  drop did;
run;

proc print;
run;
Obs    num    name

  1      1    [Content_Types].xml
  2      2    xl/worksheets/sheet1.xml
  3      3    xl/worksheets/_rels/sheet1.xml.rels
  4      4    xl/worksheets/sheet2.xml
  5      5    xl/worksheets/_rels/sheet2.xml.rels
  6      6    xl/workbook.xml
  7      7    xl/styles.xml
  8      8    xl/sharedStrings.xml
  9      9    xl/theme/theme1.xml
 10     10    docProps/app.xml
 11     11    xl/_rels/workbook.xml.rels
 12     12    docProps/core.xml
 13     13    _rels/.rels
jimbarbour
Meteorite | Level 14

@Tom,

 

Changing to a forward slash inside the Zip archive worked.  I can now read the _rels/.rels file.

 

I'm now having what appears to be a problem with the Zip engine on a SAS Filename.  I have to update a number of the xml files in order to keep everything in sync:

  • _rels/.rels
  • docProps/app.xml
  • docProps/custom.xml
  • [Content_Types].xml

Everything runs fine, but when I try to open things in Excel, I get a message that there's a problem.  Recovery fails.

jimbarbour_0-1667703758678.png

When I actually look at the contents of the xlsx file using WinZip, I typically get  a message that there's a CRC checksum mismatch.  Exactly which of the xml components gets this message varies with the order I create the xml components.  It shouldn't matter what order I create the xml components.  It seems to me that the Zip engine shouldn't be doing this.

jimbarbour_1-1667703843753.png

 

I'm running SAS 9.4 M6 on a Windows Server 2016 Standard (64 bit) machine.  My program is below.  The order of xml component creation is controlled by the  order in the DATALINES4.

 

Would you happen to have any insight here?  

 

Jim

 

Detailed messages.  I note that components that I'm not even touching are getting their CRC check sums messed up.  I think that indicates a problem with the Zip engine.

Extracting file: C:\Users\jbarbou6\Documents\SAS\Pgm\Training\Excel_Properties_ODS\Class_3.ZIP
Extracting to "C:\Users\jbarbou6\Documents\SAS\Pgm\Training\Excel_Properties_ODS\Class_3\"
Use Path: yes   Overlay Files: no
Extracting xl\worksheets\sheet1.xml
Extracting xl\sharedStrings.xml
Extracting docProps\core.xml
Extracting xl\styles.xml
Central and local directory mismatch for file "xl/styles.xml" (crc-32 - local: 1148BA33 hex  central: 3E9D0B61 hex).
Extracting docProps\app.xml
Extracting _rels\.rels
Central and local directory mismatch for file "_rels/.rels" (crc-32 - local: 1148BA33 hex  central: 52D5847E hex).
Extracting xl\_rels\workbook.xml.rels
Unable to find the local header for xl\_rels\workbook.xml.rels.
Extracting xl\workbook.xml
Central and local directory mismatch for file "xl/workbook.xml" (crc-32 - local: 721EAEAE hex  central: 4B8E0F38 hex).
Severe Error: Local and central CRC values don't match.

Program:

%Time_Stamp(START);

**	Set slash to back slash for Windows or forward slash for LINUX/UNIX	**;
%LET	Slash		=	%SYSFUNC(IFC(%EVAL(&SYSSCP = WIN),\,/));

*%LET	Iteration	=	0;

%IF	%SYMEXIST(Iteration)	%THEN
	%DO;
		%LET	Iteration	=	%EVAL(&Iteration + 1);
	%END;
%ELSE
	%DO;
		%LET	Iteration	=	1;
	%END;

%PUT	&Nte1  Running Iteration &Iteration;

%LET	Path		=	C:\Users\jbarbou6\Documents\SAS\Pgm\Training\Excel_Properties_ODS;
*%LET	Path		=	I:\commercial\user\jbarbou3\ODS_Excel;
%LET	File_Name	=	&Path.&Slash.Class_&Iteration..xlsx;

**	Create an xlsx file with Proc Export	**;
PROC	EXPORT	DATA=sashelp.class	FILE="&File_Name"	REPLACE	DBMS=xlsx;
RUN;

FILENAME	XL_File	ZIP	"&File_Name";

**------------------------- Relationships --------------------------------**;
**	Read in the .rels relationships file, add a reference to custom.xml, and write out a SAS data set containing the modified .rels xml	**;
DATA	WORK.Rels_XML;
	DROP	_:;
	INFILE	XL_File(_rels/.rels)	LENGTH=SAS_Length;
	INPUT	Line	$VARYING32767.	SAS_Length;
	_Position	=	FIND(Line, '</relationships>', 'i');
	IF	_Position	THEN
		DO;
			PUTLOG	"&Nte1  Adding custom.xml entry to spreadsheet iteration &Iteration";
			SUBSTR(Line,_Position)	=	'<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/></Relationships>';
		END;
RUN;

**------------------------- Content Types --------------------------------**;
**	Read in the Content Types XML file, add a reference to custom.xml, and write out a SAS data set containing the modified Content Types XML.	**;
DATA	WORK.Content_Types_XML;
	DROP	_:;
	INFILE	XL_File([Content_Types].xml)	LENGTH=SAS_Length;
	INPUT	Line	$VARYING32767.	SAS_Length;
	_Position	=	FIND(Line, '</Types>', 'i');
	IF	_Position	THEN
		DO;
			PUTLOG	"&Nte1  Adding custom.xml entry to spreadsheet iteration &Iteration";
			SUBSTR(Line,_Position)	=	'<Override PartName="/docProps/custom.xml" ContentType="application/vnd.openxmlformats-officedocument.custom-properties+xml"/></Types>';
		END;
RUN;

**--------------------------- Custom.XML --------------------------------**;
**	Create a SAS data set that contains the custom XML that will set the label to either External or Internal	**;
DATA	WORK.Custom_XML;
	INFILE	DATALINES4	LENGTH=SAS_Length;
	INPUT	Line	$VARYING32767.	SAS_Length;
DATALINES4;
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Enabled"><vt:lpwstr>true</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="3" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_SetDate"><vt:lpwstr>2022-11-05T21:48:26Z</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="4" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Method"><vt:lpwstr>Privileged</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="5" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_Name"><vt:lpwstr>External Label</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="6" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_SiteId"><vt:lpwstr>db05faca-c82a-4b9d-b9c5-0f64b6755421</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="7" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_ActionId"><vt:lpwstr>6d6ffa67-7505-4457-b8c1-4592fb83e3c9</vt:lpwstr></property><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="8" name="MSIP_Label_320f21ee-9bdc-4991-8abe-58f53448e302_ContentBits"><vt:lpwstr>0</vt:lpwstr></property></Properties>
;;;;
RUN;

**--------------------------- App.XML --------------------------------**;
**	Create a SAS data set that contains the App.XML that will correspond to the rest of the XML	**;
DATA	WORK.App_XML;
	INFILE	DATALINES4	LENGTH=SAS_Length;
	INPUT	Line	$VARYING32767.	SAS_Length;
DATALINES4;
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Application>Microsoft Excel</Application><DocSecurity>0</DocSecurity><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="4" baseType="variant"><vt:variant><vt:lpstr>Worksheets</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant><vt:variant><vt:lpstr>Named Ranges</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="2" baseType="lpstr"><vt:lpstr>Class_25</vt:lpstr><vt:lpstr>Class_25</vt:lpstr></vt:vector></TitlesOfParts><Company>SAS Institute Inc</Company><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0300</AppVersion></Properties>
;;;;
RUN;

**	Update/add the XML files to the xlsx file which is a Zip archive	**;
DATA	_NULL_;
	LENGTH	Mem_Name	$128;

	INFILE	DATALINES4;
	INPUT	Mem_Name	$;
	FILE	XL_File	MEMVAR=Mem_Name;
	PUTLOG	"&Nte1  1.  "	_N_=  Mem_Name=;

	IF	Mem_Name	=	'docProps/custom.xml'	THEN
		DO;
			**	Create the custom.xml file from the SAS data set that contains the custom XML that will set the label to either External or Internal	**;
			PUTLOG	"&Nte1  Processing "		Mem_Name;
			DO	UNTIL	(End_Custom);	
				SET	WORK.CUSTOM_XML				END=End_Custom;
				Leng	=	length(line);
				PUT	Line	$Varying32767.		Leng;
			END;
		END;

	IF	Mem_Name	=	'docProps/app.xml'	THEN
		DO;
			**	Create the app.xml file from the SAS data set that contains the App XML	**;
			PUTLOG	"&Nte1  Processing "		Mem_Name;
			DO	UNTIL	(End_App);	
				SET	WORK.App_XML				END=End_App;
				Leng	=	length(line);
				PUT	Line	$Varying32767.		Leng;
			END;
		END;

	IF	Mem_Name	=	'_rels/.rels'			THEN
		DO;
			**	Write the modified .rels xml to the .rels file	**;
			PUTLOG	"&Nte1  Processing "		Mem_Name;
			DO	UNTIL	(End_Rels);
				SET	WORK.Rels_XML				END=End_Rels;
				Leng	=	length(line);
				PUT	Line	$Varying32767.		Leng;
			END;
		END;

	IF	Mem_Name	=	'[Content_Types].xml'	THEN
		DO;
			**	Write the modified Content Types XML to the Content Types XML file	**;
			PUTLOG	"&Nte1  Processing "		Mem_Name;
			DO	UNTIL	(End_Content);
				SET	WORK.Content_Types_XML		END=End_Content;
				Leng	=	length(line);
				PUT	Line	$Varying32767.		Leng;
			END;
		END;

DATALINES4;
_rels/.rels
docProps/custom.xml
docProps/app.xml
[Content_Types].xml
;;;;
RUN;

%Time_Stamp(STOP);

 

 

 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 22 replies
  • 4196 views
  • 9 likes
  • 4 in conversation