Jump to content

"xsl: if test =" question


Recommended Posts

I am using an "xsl: if test =" statement in my stylesheet to conditionally transform an xml document with nodes from another xml document. The value in my test is always true because the nodes are always copied.Basically, if the identifier node values are equal, I want to copy the InvoiceLineItem from out1.xml to out2.xml. Here is my xsl: <xsl:if test="/ssdh:Identifier/text() = '.' = document('output2\out2.xml')/ssdh:Identifier/text() = '.' "> <xsl:copy-of select="document('output2\out2.xml')/tns:InvoiceNotification/tns:Invoice/tns:InvoiceLineItem"/></xsl:if>Anyone see what is wrong with my " xsl:if test =" statement?Thanks,dmhollis

Link to post
Share on other sites

I tried to shorten things a bit.... as my xml files are huge.... here's a simplified version of what I'm trying to do.out1.xml<InvoiceNotification><DocumentHeader><Identifier>22548</Identifier></DocumentHeader><Invoice><InvoiceLineItem><Line>123</Line></InvoiceLineItem></Invoice></InvoiceNotification>out2.xml<InvoiceNotification><DocumentHeader><Identifier>22549</Identifier></DocumentHeader><Invoice><InvoiceLineItem><Line>456</Line></InvoiceLineItem></Invoice></InvoiceNotification>I'm using the following from a batch file:msxsl.exe out1.xml merge.xsl -o out3.xml Here's my stylesheet merge.xsl :<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" <xsl:template match="/"><InvoiceNotification> <xsl:copy-of select="/InvoiceNotification/DocumentHeader"/> <Invoice> <xsl:copy-of select="/InvoiceNotification/Invoice/InvoiceLineItem"/> <xsl:if test="/InvoiceNotification/DocumentHeader/Identifier = document ('out2.xml')/InvoiceNotification/DocumentHeader/Identifier "> <xsl:copy-of select="document('out2.xml')/InvoiceNotification/Invoice/InvoiceLineItem"/> </xsl:if></Invoice></InvoiceNotification> </xsl:template></xsl:stylesheet> The InvoiceLineItem is copied whether the Identifier in out1.xml and out2.xml is the same or not....Hope this helps clarify!Thanks,dmhollis

Edited by dmhollis
Link to post
Share on other sites

***I took off the /text() = '.' part of the" xsl if test =" expression and it seems to work ( see above edited post) ..... however, I still can't get the full xml files including namespaces and all data to cooperate. Any thoughts on this syntax and why it works here without the /text() = '.' part of the expression ?

Link to post
Share on other sites

not sure about text() at present, and I haven't had a lot of problems involving namespaces, but if you could elaborate on 'cooperate' a bit I might be able to helppresuming (perhapps incorrectly) that these files have more than a single set of InvoiceNotification, Invoice or InvoiceLineItem you might need to incorporate a for-each, apply-templates or call-template to handle the iteration.../InvoiceNotification/Invoice/InvoiceLineItemimplies:/InvoiceNotification/Invoice[1]/InvoiceLineItem[1]not sure thats any help

Link to post
Share on other sites

thanks for the reply.... really wanted to make sure I was on the right track with my xsl.when I use this stylesheet with the real files and namespaces without the text() = '.' portion of the expression.... I never get a true condition ( so my InvoiceLineItem nodes never get copied from the out2.xml document ). Because this latest expression works... I think I'm getting close... I'm just not understanding the value that is being generated by the test expression.. wish there was a way to debug xslt. My real documents are pretty big, but not all that complicated. I'm only looking to copy one InvoiceLineItem per document.

Link to post
Share on other sites

In a pinch you cna d/l a demo of XmlSpy, that will let you step debug xsl transforms, think the newer version of MS Visual Studio does this as well - same thing a demo can help in a pinchI have trouble with the syntax in this line; <xsl:if test="/ssdh:Identifier/text() = '.' = document('output2\out2.xml')/ssdh:Identifier/text() = '.' ">as Martin mentioned the = in the middle looks out of place, I'd expect this to pop.Are you looking to match two identifiers when they are each equal to a literal '.' character?Also the above wouldn't match because its going to look for ssdh:Identifier as the xml document root element; xpath below looks correctthis one seems syntactically correct:<xsl:if test="/InvoiceNotification/DocumentHeader/Identifier = document ('out2.xml')/InvoiceNotification/DocumentHeader/Identifier ">but you say it doesn't work when you add text() to the end of the xpath selectors?

Link to post
Share on other sites

one more really dumb question / observation; given the example - those documents shouldn't match because they have different identifiers? <Identifier>22548</Identifier><Identifier>22549</Identifier>

Link to post
Share on other sites

I'm close to the answer I think.... This one definitely works with my simple test example files listed above:<xsl:if test="/InvoiceNotification/DocumentHeader/Identifier = document('out2.xml')/InvoiceNotification/DocumentHeader/Identifier"> <xsl:copy-of select="document('out2.xml')/InvoiceNotification/Invoice/InvoiceLineItem"/> </xsl:if>But if I apply that same to the real more complicated files.... I never get a true condition, so no copy of InvoiceLineItem.However, If I apply the original expression with the = in the middle:<xsl:if test="/tns:InvoiceNotification/ssdh:DocumentHeader/ssdh:DocumentInformation/ssdh:Creation/ssdh:DocumentIdentification/ssdh:Identifier/text()='.' = document('\out2.xml')/tns:InvoiceNotification/ssdh:DocumentHeader/ssdh:DocumentInformation/ssdh:Creation/ssdh:DocumentIdentification/ssdh:Identifier/text()='.'">I get a constant true condition, whether the Identifier node is equal or not...

Link to post
Share on other sites

your later is matching because ( false == false ) == true<xsl:if test=" //foo='.' = //bar='.'"><xsl:if test="false()=false()">these both evaluate to true

Link to post
Share on other sites

Thanks for your input packrat.... I knew it was going to come down to double checking everything. Turns out, my expression had one extra node in the document path... now the below expression works great.<xsl:if test="/tns:InvoiceNotification/ssdh:DocumentHeader/ssdh:DocumentInformation/ssdh:DocumentIdentification/ssdh:Identifier = document('out2.xml')/tns:InvoiceNotification/ssdh:DocumentHeader/ssdh:DocumentInformation/ssdh:DocumentIdentification/ssdh:Identifier">Thanks again for the extra set of eyes and helpful suggestions.dmhollis

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...