[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Hi,
I have a source xml that needs to be inserted with new contents from a separate xml file.
source xml:
reference xml:
<root>
<entry id="1" type="T" n="1"/>(<xref target="1" type="T" n="1">1</xref>) <!-- more nodes here 1 --><entry id="1" type="T" n="1" n-mod="a"/>(<xref target="1" type="T" n="1a">1a</xref>) <!-- more nodes here 2 --><entry id="1" type="T" n="1-5"/>(<xref target="1" type="T" n="1-5">1-5</xref>) <!-- more nodes here 3 --><entry id="1" type="T" n="2"/>(<xref target="1" type="T" n="2">2</xref>) <!-- more nodes here 4 -->
</root>
target xml output:
Basically the requirements is for each entry in the source xml, look for a corresponding entry element in the reference xml (with same attributes) get the nodes after the (<xref></xref>) nodes and insert it after the entry as a child of a new.entry element.
I think that this is possible using keys, however i'm not that familiar with the use of keys.
This is my xsl file:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>
<xsl:param name="new.entry.file" as="xs:anyURI"/>
<xsl:variable name="new.entries" as="element()+" select="document($new.entry.file)//entry"/>
<xsl:key name="new.entry" match="node()[name()!='entry']" use="generate-id(preceding-sibling::entry[1])"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="entry">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:if test="if (exists(@n-mode)) then exists($new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n][@n-mod=current()/@n-mod]) else exists($new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n])">
<new.entry>
<xsl:apply-templates select="if (exists(@n-mode)) then $new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n][@n-mod=current()/@n-mod]/key('new.entry',generate-id())[position()>3] else $new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n][not(exists(@n-mod))]/key('new.entry',generate-id())[position()>3]"/>
</new.entry>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
And using saxon8 I get this:
[xsl] Grouping and Insertion
Subject: [xsl] Grouping and Insertion From: Jeff Sese <jsese@xxxxxxxxxxxx> Date: Fri, 17 Nov 2006 16:13:00 +0800 |
Hi,
I have a source xml that needs to be inserted with new contents from a separate xml file.
source xml:
<root> <entry id="1" type="T" n="1"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="1" n-mod="a"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="2"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="3"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="4"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="5"> <!-- some more nodes here --> </entry> </root>
reference xml:
<root>
<entry id="1" type="T" n="1"/>(<xref target="1" type="T" n="1">1</xref>) <!-- more nodes here 1 --><entry id="1" type="T" n="1" n-mod="a"/>(<xref target="1" type="T" n="1a">1a</xref>) <!-- more nodes here 2 --><entry id="1" type="T" n="1-5"/>(<xref target="1" type="T" n="1-5">1-5</xref>) <!-- more nodes here 3 --><entry id="1" type="T" n="2"/>(<xref target="1" type="T" n="2">2</xref>) <!-- more nodes here 4 -->
</root>
target xml output:
<root> <entry id="1" type="T" n="1"> <!-- some more nodes here --> </entry> <new.entry> <!-- more nodes here 1 --> </new.entry> <entry id="1" type="T" n="1" n-mod="a"> <!-- some more nodes here --> </entry> <new.entry> <!-- more nodes here 2 --> </new.entry> <entry id="1" type="T" n="2"> <!-- some more nodes here --> </entry> <new.entry> <!-- more nodes here 4 --> </new.entry> <entry id="1" type="T" n="3"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="4"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="5"> <!-- some more nodes here --> </entry> <new.entry> <!-- more nodes here 3 --> </new.entry> </root>
Basically the requirements is for each entry in the source xml, look for a corresponding entry element in the reference xml (with same attributes) get the nodes after the (<xref></xref>) nodes and insert it after the entry as a child of a new.entry element.
I think that this is possible using keys, however i'm not that familiar with the use of keys.
This is my xsl file:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>
<xsl:param name="new.entry.file" as="xs:anyURI"/>
<xsl:variable name="new.entries" as="element()+" select="document($new.entry.file)//entry"/>
<xsl:key name="new.entry" match="node()[name()!='entry']" use="generate-id(preceding-sibling::entry[1])"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="entry">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:if test="if (exists(@n-mode)) then exists($new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n][@n-mod=current()/@n-mod]) else exists($new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n])">
<new.entry>
<xsl:apply-templates select="if (exists(@n-mode)) then $new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n][@n-mod=current()/@n-mod]/key('new.entry',generate-id())[position()>3] else $new.entries[@id=current()/@id][@type=current()/@type][@n=current()/@n][not(exists(@n-mod))]/key('new.entry',generate-id())[position()>3]"/>
</new.entry>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
And using saxon8 I get this:
<?xml version="1.0" encoding="UTF-8"?> <root> <entry id="1" type="T" n="1"> <!-- some more nodes here --> </entry> <new.entry><!-- more nodes here 1 --></new.entry> <entry id="1" type="T" n="1" n-mod="a"> <!-- some more nodes here --> </entry> <new.entry><!-- more nodes here 1 --></new.entry> <entry id="1" type="T" n="2"> <!-- some more nodes here --> </entry> <new.entry><!-- more nodes here 4 --></new.entry> <entry id="1" type="T" n="3"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="4"> <!-- some more nodes here --> </entry> <entry id="1" type="T" n="5"> <!-- some more nodes here --> </entry> </root>
-- *Jeferson L. Sese* Asiatype Incorporated Suite 114, Columbia Tower, Ortigas Ave., Greenhills, Mandaluyong City 1550 Philippines
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XQuery and XSLT, Evan Lenz | Thread | Re: [xsl] Grouping and Insertion, Florent Georges |
Re: [xsl] attribute of a single-tag, Nico Van Cleemput | Date | RE: [xsl] XQuery and XSLT, Michael Kay |
Month |