I am running a batch file using msxsl to take an input xml file like below

<ns1:invoicedata>
<data1>1</data1>
<data2>2</data2>
</ns1:invoicedata>

I need to copy this original output and replace the values with the input file values

<ns2:invoiceoutput>
<data3>3</data3>
<data4>4</data4>
<data5>5</data5>
</ns2:invoiceoutput>

so that it ends up with the following data in it

<ns2:invoiceoutput>
<data3>1</data3>
<data4>2</data4>
<data5>5</data5>
</ns2:invoiceoutput>

I've tried template matching... value-of select= statements, choose, etc... but I can't
seem to get the desired output. Just started using xsl and it seems doable... anyone?
Thanks!

Recommended Answers

All 5 Replies

I'm confused as to what you're trying to do. Do you have input documents? How do you know which invoice in one document is supposed to be paired with an invoice in another document? Also XSLT 1.0 or 2.0? Please post a better description of the problem with your sample inputs IN CODEBOXES and I'll take a look. This is certainly doable in xslt.

Thanks for the reply... I am trying to take an input file that has xml order data and use msxsl.exe (1.0 pretty old, probably ) and run it as a batch file to modify an output message file. Something like this...

msxsl.exe invoice.xml adddata.xsl -o test_out.xml

So, my input is the invoice.xml, I run the transformation with adddata.xsl to produce the output test_out.xml. All I'm trying to do is take the data from the input file and modify specific elements of the output file.

I copied the original output file with the following:

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>

Then, I tried using template matches to select the elements from the input file whose data I want to modify the output file with

<xsl:template match="/">
  <xsl:element name="InvoiceNotification">
      <xsl:apply-templates select="EInvoiceData/CustOrdNumber"/>
   </xsl:element>
</xsl:template>

<xsl:template match="EInvoiceData/CustOrdNumber">
   <xsl:element name="tns:PurchaseOrderNumber/dp:Identifier" >
      <xsl:value-of select="."/>
   </xsl:element>
</xsl:template>

This is a one for one transformation.... one input xml file is created per invoice, so all I need to do is get this input file data into the stock output file and I should have what I need.

Sorry about format... I haven't posted much development code... but here is a snippet of the input xml file

<EInvoiceData>
<InvoiceDate>1070108</InvoiceDate>
<CustomerNumber>4638501</CustomerNumber>
<InvoiceNumber>59925</InvoiceNumber>
<CustOrdNumber>R11-9838021</CustOrdNumber>
</EInvoiceData>

Here is the output xml I need to transform :

<tns:InvoiceNotification>
<tns:Invoice>
<tns:BillFrom>
<tns:PurchaseOrderNumber>
<dp:Identifier>XXXXXXX</dp:Identifier>
</tns:PurchaseOrderNumber>
</tns:BillFrom>
</tns:Invoice>
</tns:InvoiceNotification>

I would be trying to find a match in the input for CustOrdNumber and get that into the output files PurchaseOrderNumber/Identifier element.

I hope that clears it up a bit...

Thanks!

Here ya go. Since you didn't give me namespace definitions for the tns: and dp: namespace I just made it up. Make sure you change those to whatever namesapce that you need in the transformation.

Input

<EInvoiceData>
	<InvoiceDate>1070108</InvoiceDate>
	<CustomerNumber>4638501</CustomerNumber>
	<InvoiceNumber>59925</InvoiceNumber>
	<CustOrdNumber>R11-9838021</CustOrdNumber>
</EInvoiceData>

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="SOMETHINGELSE" xmlns:tns="SOMENAMESPACE" >

	<xsl:template match="/">
		<xsl:apply-templates select="EInvoiceData"/>
	</xsl:template>

	<xsl:template match="EInvoiceData" >
		<tns:InvoiceNotification>
			<tns:Invoice>
				<tns:BillFrom>
					<xsl:apply-templates select="CustOrdNumber" />
				</tns:BillFrom>
			</tns:Invoice>
		</tns:InvoiceNotification>			
	</xsl:template>

	<xsl:template match="CustOrdNumber" >
		<tns:PurchaseOrderNumber>
			<dp:Identifier>
				<xsl:value-of 	select="." />
			</dp:Identifier>
		</tns:PurchaseOrderNumber>
	</xsl:template>	
</xsl:stylesheet>

Output

<tns:InvoiceNotification xmlns:dp="SOMETHINGELSE" xmlns:tns="SOMENAMESPACE">
	<tns:Invoice>
		<tns:BillFrom>
			<tns:PurchaseOrderNumber>
				<dp:Identifier>R11-9838021</dp:Identifier>
			</tns:PurchaseOrderNumber>
		</tns:BillFrom>
	</tns:Invoice>
</tns:InvoiceNotification>

i use the way with intern DTD
so i make a xmltogether to put the two xml in one xml file

<?xml version="1.0"?>
<!DOCTYPE root[
  <!ENTITY xml1 SYSTEM "invoicedata.xml">
  <!ENTITY xml2 SYSTEM "invoiceoutput.xml">  
]>
<root>
  &xml1;
  &xml2;  
</root>

so you can use xlt

use namespace and exclude namespace1

you found the documentroot in the together xmlfile
store in variable datei1 the value all node you wanted to compare

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="http://my.com/mynamespace2" xmlns:ns1="http://my.com/mynamespace1" exclude-result-prefixes="ns1">
	<xsl:output method="xml" indent="yes"/>
	<xsl:variable name="datei1" select="//root/ns1:invoicedata/child::*[contains(local-name(.),'data')]"/>
	<xsl:template match="/">
		<ns2:invoiceoutput xmlns:ns2="http://my.com/mynamespace2">
			<xsl:apply-templates select="root"/>
		</ns2:invoiceoutput>
	</xsl:template>
	<xsl:template match="root">
		<xsl:apply-templates select="ns2:invoiceoutput"/>
	</xsl:template>
	<xsl:template match="ns2:invoiceoutput">
		<xsl:apply-templates select="child::*[contains(local-name(.),'data')]"/>
	</xsl:template>
	<xsl:template match="*">
		<xsl:variable name="dataname" select="local-name(.)"/>
		<xsl:variable name="pos" select="position()"/>
		<xsl:choose>
			<xsl:when test="$datei1[$pos]">
				<xsl:element name="{$dataname}">
					<xsl:value-of select="$datei1[$pos]"/>
				</xsl:element>
			</xsl:when>
			<xsl:otherwise>
				<xsl:element name="{$dataname}">
					<xsl:value-of select="."/>
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>

result

<?xml version='1.0' ?>
<ns2:invoiceoutput xmlns:ns2="http://my.com/mynamespace2">
  <data3>1</data3>
  <data4>2</data4>
  <data5>5</data5>
</ns2:invoiceoutput>

Thanks for the helpful input.... I knew I was almost on track... but couldn't quite get there. Now my batch file is transforming like a champ!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.