Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 26th, 2008, 09:11 AM
Registered User
 
Join Date: Aug 2008
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default Compare values in different nodes

I need to copy the values of some nodes only if the values of these nodes != values in some other nodes.

example input:

<...>
<nodes>
<node>
AAAA
</node>
<node>
BBBB
</node>
...
</nodes>
<...>
<dont_copy>
<values>
<value>
AAAA
</value>
</values>
<...>

The output should be:

<node>
BBBB
</node>
<node>
...

It is somewhat difficult to explain but anyone know how to accomplish this?



 
Old August 26th, 2008, 09:15 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Two template rules:

<xsl:template match="node">
  <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="node[.=//dont_copy/values/value]"/>



Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old August 26th, 2008, 09:16 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Code:
<xsl:copy-of
  select="//nodes/node[not(. = //dont_copy/values/value)]"/>
--
  Martin Honnen
  Microsoft MVP - XML
 
Old August 27th, 2008, 02:42 AM
Registered User
 
Join Date: Aug 2008
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hmm still cant get it to work, I think I was a bit unclear in my example input. So how about this one:

Code:
<root>
    <nodes>
        <node>
            <name>
                AAA
            </name>
            <value>
                1
            </value>
        </node>
        <node>
            <name>
                BBB
            </name>
            <value>
                2
            </value>
        </node>
        <node>
            <name>
                CCC
            </name>
            <value>
                3
            </value>
        </node>
        ...
    </nodes>
    ...
    <items>
        <item>
            <name>
                AAA
            </name>
        </item>
        <item>
            <name>
                CCC
            </name>
        </item>
        <item>
            ...
        </item>
        ...
    </items>
    ...
</root>
And the result should become something like:

Code:
<root>
    <nodes>
        <node>
            <name>
                BBB
            </name>
        </node>
        <node>
            ...
        </node>
        <node>
            ...
        </node>
    </nodes>
</root>
I think if I only have to compare to one node to not copy, I could get it to work but since it is a list of values that I have to compare to Id need some kind of loop right? I just started with XSLT yesterday (need it in my BizTalk solution) so if you guys could explain like you would to an idiot I would appreciate it!

 
Old August 27th, 2008, 02:46 AM
Registered User
 
Join Date: Aug 2008
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Oops output should be something like:

Code:
<root>
    <nodes>
        <node>
            <name>
                BBB
            </name>
            <value>
                2
            </value>
        </node>
        <node>
            ...
        </node>
        <node>
            ...
        </node>
    </nodes>
</root>
 
Old August 27th, 2008, 06:30 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Here is a sample stylesheet:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

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

  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates select="@* | nodes"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node[name = /root/items/item/name]"/>

</xsl:stylesheet>
When applied to this input XML
Code:
<root>
    <nodes>
        <node>
            <name>
                AAA
            </name>
            <value>
                1
            </value>
        </node>
        <node>
            <name>
                BBB
            </name>
            <value>
                2
            </value>
        </node>
        <node>
            <name>
                CCC
            </name>
            <value>
                3
            </value>
        </node>
    </nodes>
    <items>
        <item>
            <name>
                AAA
            </name>
        </item>
        <item>
            <name>
                CCC
            </name>
        </item>

    </items>

</root>
then the result with Saxon 6.5.5 is
Code:
<?xml version="1.0" encoding="utf-8"?><root><nodes>

        <node>
            <name>
                BBB
            </name>
            <value>
                2
            </value>
        </node>

    </nodes></root>
The stylesheet uses the identity transformation template and then has two additional templates, one for the 'root' element to make sure that only the 'nodes' elements are processed but not the 'items' elements, and one empty template for 'node[name = /root/items/item/name]' elements to ensure that these are not copied. That should suffice, no need for any loops.


--
  Martin Honnen
  Microsoft MVP - XML
 
Old September 11th, 2008, 05:34 AM
Registered User
 
Join Date: Aug 2008
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks, Ive been busy for a while so unfortunately I still haven't gotten this to work.

I use the following xslt (nodes where Addition_Name = addition_name shouldn't be copied):

Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  targetNamespace="http://DataRegisterRequest"
  version="1.0">

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

    <xsl:template match="*[local-name()='Root']">
        <xsl:apply-templates select="//*[local-name()='ADDITIONS']"/>
    </xsl:template>

    <xsl:template match="*[local-name()='ADDITION'][*[local-name()='Addition_Name'] = //*[local-name()='KLNOrder']//*[local-name()='addition_name']]"/>

</xsl:stylesheet>
Now only the nodes that are supposed to be copied are actually copied. But there is still a problem with the namespaces. The resulting XML file has the same namespace as the original XML. I need the new XML to have a namespace defined by me. How can I accomplish this with my current xslt?

 
Old September 11th, 2008, 05:36 AM
Registered User
 
Join Date: Aug 2008
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

There is an error in the prev post. Here is my XSLT:

Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

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

    <xsl:template match="*[local-name()='Root']">
        <xsl:apply-templates select="//*[local-name()='ADDITIONS']"/>
    </xsl:template>

    <xsl:template match="*[local-name()='ADDITION'][*[local-name()='Addition_Name'] = //*[local-name()='KLNOrder']//*[local-name()='addition_name']]"/>

</xsl:stylesheet>
 
Old September 11th, 2008, 05:57 AM
samjudson's Avatar
Friend of Wrox
 
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

For elements you'd do something like this:

Code:
<xsl:template match="node()">
        <xsl:element name="{local-name()}" namespace="http://newnamespace.com">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
</xsl:template>
and the same for attributes:

Code:
<xsl:template match="@*">
        <xsl:attribute name="{local-name()}" namespace="http://newnamespace.com">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>




/- Sam Judson : Wrox Technical Editor -/
 
Old September 11th, 2008, 06:25 AM
Registered User
 
Join Date: Aug 2008
Posts: 6
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Here is how I managed to solve it:

Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ns0="mynamespace"
  version="1.0">

    <xsl:template match="*[local-name()='Addition_Name']">
        <Addition_Name>
            <xsl:value-of select="."/>
        </Addition_Name>
    </xsl:template>

    <xsl:template match="*[local-name()='Addition_Value']">
        <Addition_Value>
            <xsl:value-of select="."/>
        </Addition_Value>
    </xsl:template>

    <xsl:template match="*[local-name()='Root']">
        <ns0:ADDITIONS>
            <xsl:apply-templates select="//*[local-name()='ADDITIONS']"/>
        </ns0:ADDITIONS>
    </xsl:template>

    <xsl:template match="*[local-name()='ADDITION'][*[local-name()='Addition_Name'] = //*[local-name()='KLNOrder']//*[local-name()='addition_name']]"/>

</xsl:stylesheet>
I find it really tricky to understand how XSLT works, but when I finally figure out how to do something in XSLT it just seems so obvious...






Similar Threads
Thread Thread Starter Forum Replies Last Post
XML + XSLT Compare Nodes tommyready XSLT 5 September 5th, 2007 03:18 AM
How to compare two lat/long values chandup SQL Server 2000 1 May 17th, 2007 05:07 AM
compare values in one row to the next tholleran SQL Server 2000 7 March 22nd, 2007 04:45 PM
Compare "before and after" values on a form? wayne62682 Classic ASP Basics 3 May 17th, 2006 03:13 AM
How to compare nodes from 2 XML docs kwilliams XSLT 0 August 30th, 2005 01:43 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.