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 May 2nd, 2007, 06:46 AM
Registered User
 
Join Date: May 2007
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default Conditional select previous records' value

Hello,
I am trying to extract a value from the XML below based on the value of the previous record before the current record. Basically, if the Textseq-id_accession of the previous record starts-with 'NM_' I want to to select that value as the 2nd "column" in my output. I have tried preceding and ancestor but the either take me to the top of the document or shows the NP_ value rather than the NM_.

<?xml version="1.0"?>
<Bioseq-set>
  <Bioseq-set_seq-set>
    <Seq-entry>
      <Seq-entry_set>
        <Bioseq-set>
          <Bioseq-set_seq-set>
            <Seq-entry>
              <Seq-entry_seq>
                <Bioseq>
                  <Bioseq_id>
                    <Seq-id>
                      <Seq-id_other>
                        <Textseq-id>
                          <Textseq-id_accession>NM_201656</Textseq-id_accession>
                          <Textseq-id_version>1</Textseq-id_version>
                        </Textseq-id>
                      </Seq-id_other>
                    </Seq-id>
                  </Bioseq_id>
                </Bioseq>
              </Seq-entry_seq>
            </Seq-entry>
            <Seq-entry>
              <Seq-entry_seq>
                <Bioseq>
                  <Bioseq_id>
                    <Seq-id>
                      <Seq-id_other>
                        <Textseq-id>
                          <Textseq-id_accession>NP_973385</Textseq-id_accession>
                          <Textseq-id_version>1</Textseq-id_version>
                        </Textseq-id>
                      </Seq-id_other>
                    </Seq-id>
                  </Bioseq_id>
                </Bioseq>
              </Seq-entry_seq>
            </Seq-entry>
          </Bioseq-set_seq-set>
        </Bioseq-set>
      </Seq-entry_set>
    </Seq-entry>
  </Bioseq-set_seq-set>
</Bioseq-set>

My current XSL looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output method="text" encoding="ISO-8859-1" />


        <xsl:template match="/">
            <xsl:apply-templates
                select=".//Bioseq-set/Bioseq-set_seq-set/Seq-entry/Seq-entry_set/Bioseq-set/Bioseq-set_seq-set/Seq-entry"
                mode="DocRoot" />
        </xsl:template>


        <xsl:template match="Seq-entry" mode="DocRoot">
            <xsl:for-each select="Seq-entry_seq/Bioseq/Bioseq_id/Seq-id/Seq-id_other/Textseq-id">
                <xsl:if test="starts-with(Textseq-id_accession,'NP_')">

                    <xsl:value-of
                        select="Textseq-id_accession"/>
                    <xsl:text disable-output-escaping="yes">&lt;&gt;</xsl:text>

                    <xsl:value-of select="ancestor::Seq-entry_seq/Bioseq/Bioseq_id/Seq-id/Seq-id_other/Textseq-id/Textseq-id_accession"/>
<xsl:text disable-output-escaping="yes">&lt;&gt;
</xsl:text>
                </xsl:if>
            </xsl:for-each>
        </xsl:template>

</xsl:stylesheet>

Output currently is:
NP_973385<>NP_973385<>

Should be
NP_973385<>NM_201656<>

And if the previous Textseq-id_accession was not like NM_, then a blank should be returned.

I have looked at Jeni's pages, but I am a bit baffled by all the grouping as I am not sure if that is what I want (looking at some other posts here they seem to want something slightly different).
 
Old May 2nd, 2007, 01:00 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

First, I'm wondering when I read:

<xsl:template match="/">
            <xsl:apply-templates
                select=".//Bioseq-set/

whether you really want to read all the descendant Bioseq-set elements here, or only the one at the top level? If you only want the top-level, then searching the whole document for it is very inefficient.

Secondly, when you're using output method="text" then you don't need disable-output-escaping, because the text output method never does any escaping in the first place.

Looking at this expression:

<xsl:value-of select="ancestor::Seq-entry_seq/Bioseq/Bioseq_id/Seq-id/Seq-id_other/Textseq-id/Textseq-id_accession"/>

when you're positioned in the NP_973385 entry the only ancestor Seq-entry_seq is within the second of the two Seq_entry elements, so I can't see why you imagine it will select something within the first Seq_entry. From your description, I would think the right path expression is

<xsl:value-of select="ancestor::Seq-entry/preceding-sibling::Seq-entry[1]/Seq-entry_seq/Bioseq/Bioseq_id/Seq-id/Seq-id_other/Textseq-id/Textseq-id_accession"/>

or perhaps more simply

<xsl:value-of select="preceding::Textseq-id_accession[1]"/>

Michael Kay

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 3rd, 2007, 05:04 AM
Registered User
 
Join Date: May 2007
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks very much Michael, this was very helpful. I understand my mistake with the ancestor now. For the template macthing the root. Do you mean there is a syntax issue with the .// or is there something else I am not understanding. The Bioseq-set is the top level of the document - I was just wanting to start from the top of the document and move down to the Seq-entry records.

 
Old May 3rd, 2007, 08:50 AM
Registered User
 
Join Date: May 2007
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hello All again. Here is my next problem, similar to above. I have attached a sample of the xml. The XML is split into Seq-entry records. For those Seq-entry records whose "Textseq-id_accession" starts-with 'NP_', I pull out some extra information. Unfortunately, it seems that I need the "GeneID" value of the NP record. The GeneID is stored in another Seq-entry record. The GeneID for each NP record is held in just one record under the
<Bioseq-set>
  <Bioseq-set_seq-set>
    <Seq-entry>
      <Seq-entry_set>
        <Bioseq-set>
          <Bioseq-set_seq-set>
record-set (the first Seq-entry record here has a "Textseq-id_accession" that does not start with NP). For each GeneID there is a link to the NP record in the "Gene-ref_locus-tag" tag. This tag in the gene record matches the
           <Seq-entry>
              <Seq-entry_seq>
                <Bioseq>
                  <Bioseq_id>
                    <Seq-id>
                      <Seq-id_general>
                        <Dbtag>
                          <Dbtag_tag>
                            <Object-id>
                              <Object-id_str>
tag of the NP record. How can I go through each NP record and extract the GeneID value from the 1st record based on the matching of the Gene-ref_locus-tag and the Object-id_str?

<?xml version="1.0" encoding="UTF-8"?>
<Bioseq-set>
  <Bioseq-set_seq-set>
    <Seq-entry>
      <Seq-entry_set>
        <Bioseq-set>
          <Bioseq-set_seq-set>
            <Seq-entry>
              <Seq-entry_seq>
                <Bioseq>
                  <Bioseq_id>
                    <Seq-id>
                      <Seq-id_other>
                        <Textseq-id>
                          <Textseq-id_accession>NC_005054</Textseq-id_accession>
                          <Textseq-id_version>1</Textseq-id_version>
                        </Textseq-id>
                      </Seq-id_other>
                    </Seq-id>
                  </Bioseq_id>
                  <Bioseq_annot>
                    <Seq-annot>
                      <Seq-annot_data>
                        <Seq-annot_data_ftable>
                          <Seq-feat>
                            <Seq-feat_data>
                                <Gene-ref>
                                  <Gene-ref_locus>repA</Gene-ref_locus>
                                  <Gene-ref_locus-tag>VRA0001</Gene-ref_locus-tag>
                                </Gene-ref>
                            </Seq-feat_data>
                            <Seq-feat_dbxref>
                              <Dbtag>
                                <Dbtag_db>GeneID</Dbtag_db>
                                <Dbtag_tag>
                                  <Object-id>
                                    <Object-id_id>2598373</Object-id_id>
                                  </Object-id>
                                </Dbtag_tag>
                              </Dbtag>
                            </Seq-feat_dbxref>
                          </Seq-feat>
                          <Seq-feat>
                            <Seq-feat_data>
                                <Gene-ref>
                                  <Gene-ref_locus-tag>VRA0002</Gene-ref_locus-tag>
                                </Gene-ref>
                            </Seq-feat_data>
                            <Seq-feat_dbxref>
                              <Dbtag>
                                <Dbtag_db>GeneID</Dbtag_db>
                                <Dbtag_tag>
                                  <Object-id>
                                    <Object-id_id>2598374</Object-id_id>
                                  </Object-id>
                                </Dbtag_tag>
                              </Dbtag>
                            </Seq-feat_dbxref>
                          </Seq-feat>
                        </Seq-annot_data_ftable>
                      </Seq-annot_data>
                    </Seq-annot>
                  </Bioseq_annot>
                </Bioseq>
              </Seq-entry_seq>
            </Seq-entry>
            <Seq-entry>
              <Seq-entry_seq>
                <Bioseq>
                  <Bioseq_id>
                    <Seq-id>
                      <Seq-id_general>
                        <Dbtag>
                          <Dbtag_tag>
                            <Object-id>
                              <Object-id_str>VRA0001</Object-id_str>
                            </Object-id>
                          </Dbtag_tag>
                        </Dbtag>
                      </Seq-id_general>
                    </Seq-id>
                    <Seq-id>
                      <Seq-id_other>
                        <Textseq-id>
                          <Textseq-id_accession>NP_877980</Textseq-id_accession>
                          <Textseq-id_version>1</Textseq-id_version>
                        </Textseq-id>
                      </Seq-id_other>
                    </Seq-id>
                  </Bioseq_id>
                </Bioseq>
              </Seq-entry_seq>
            </Seq-entry>
            <Seq-entry>
                <Seq-entry_seq>
                    <Bioseq>
                        <Bioseq_id>
                            <Seq-id>
                                <Seq-id_general>
                                    <Dbtag>
                                        <Dbtag_tag>
                                            <Object-id>
                                                <Object-id_str>VRA0002</Object-id_str>
                                            </Object-id>
                                        </Dbtag_tag>
                                    </Dbtag>
                                </Seq-id_general>
                            </Seq-id>
                            <Seq-id>
                                <Seq-id_other>
                                    <Textseq-id>
                                        <Textseq-id_accession>NP_877981</Textseq-id_accession>
                                        <Textseq-id_version>1</Textseq-id_version>
                                    </Textseq-id>
                                </Seq-id_other>
                            </Seq-id>
                        </Bioseq_id>
                    </Bioseq>
                </Seq-entry_seq>
            </Seq-entry>
          </Bioseq-set_seq-set>
        </Bioseq-set>
      </Seq-entry_set>
    </Seq-entry>
  </Bioseq-set_seq-set>
</Bioseq-set>

The XSL I have so far is :

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" encoding="ISO-8859-1" />


   <xsl:template match="/">
      <xsl:apply-templates
          select=".//Bioseq-set/Bioseq-set_seq-set/Seq-entry/Seq-entry_set/Bioseq-set/Bioseq-set_seq-set/Seq-entry"
          mode="DocRoot" />
   </xsl:template>


    <xsl:template match="Seq-entry" mode="DocRoot">
        <xsl:for-each select="Seq-entry_seq/Bioseq/Bioseq_id/Seq-id/Seq-id_other/Textseq-id">
            <xsl:if test="starts-with(Textseq-id_accession,'NP_')">

                <xsl:value-of select="Textseq-id_accession"/>
                        <xsl:text>&lt;&gt;</xsl:text>


<xsl:text >
</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

 </xsl:transform>

Output would be

NP_877980<>2598373
NP_877981<>2598374

 
Old May 3rd, 2007, 01:31 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Do you mean there is a syntax issue with the .//

No, I didn't suggest it was a syntax error, I just asked why you were using .//x when it appears that x would suffice, given that .//x is searching the whole document while x finds the required element immediately. Of course I haven't the faintest idea of the semantics of your (rather peculiar) XML, so I've no idea whether your code is right or wrong.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 4th, 2007, 03:28 AM
Registered User
 
Join Date: May 2007
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks for your clarification. I had just used the .// as I had seen that used in another XSL. I am having to learn this on the fly so I have taken your advice on board and have changed the XSL appropriately.
Many thanks
Steve.





Similar Threads
Thread Thread Starter Forum Replies Last Post
Advanced Conditional Select elite SQL Language 3 August 3rd, 2008 08:09 PM
how i can select this records dhua SQL Server 2000 0 February 8th, 2007 11:56 PM
Need Expert Advice - Checking Previous Records Zippyfrog Access VBA 4 July 15th, 2006 09:17 AM
Conditional Select problem rodmcleay SQL Server 2000 3 September 7th, 2005 07:42 PM
Previous/Next records in asp Nicky2k Classic ASP Basics 2 January 24th, 2004 05:39 AM





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