XSLT: Generate ID

Here should go questions about transforming XML with XSLT and FOP.
HuubT
Posts: 4

XSLT: Generate ID

Fri Sep 14, 2018 2:39 pm

Hello,

I am new to XSLT transformation and looking for someone some get me on the way.

I have this (example) XML:

<Loonaangifte xmlns="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01 loonaangifte.xsd" version="2.0">
<AdministratieveEenheid>
<TijdvakAangifte>
<Date>01-01-2018</Date>
</TijdvakAangifte>
<TijdvakAangifte>
<Date>02-01-2018</Date>
</TijdvakAangifte>
<TijdvakAangifte>
<Date>03-01-2018</Date>
</TijdvakAangifte>
</AdministratieveEenheid>
</Loonaangifte>

I want to insert an ID <TijdvakAangifteId> before the <Date> field.
Could anyone please provide me with a proper .xls file to achieve this.

Many thanks!

HuubT
Martin Honnen
Posts: 43

Re: XSLT: Generate ID

Fri Sep 14, 2018 4:53 pm

So what kind of ID are you looking for?

In general assuming you have a version of oXygen that supports XSLT 3 all such stylesheet that need to perform a transformation of some nodes but keep the rest of the document unchanged would start with

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   exclude-result-prefixes="#all"
   version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>
 
</xsl:stylesheet>


then, as your input elements are in a certain namespace and you want to match them you would declare that namespace as the xpath-default-namespace with e.g.

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xpath-default-namespace="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   exclude-result-prefixes="#all"
   version="3.0">


and as you also want to create new elements in your XSLT declare the namespace there as the default namespace

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xpath-default-namespace="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   xmlns="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   exclude-result-prefixes="#all"
   version="3.0">


and now you are ready to write template for those elements you want to transform/change so you want e.g.

Code: Select all

  <xsl:template match="TijdvakAangifte/Date">
      <TijdvakAangifteId>
          <xsl:number count="TijdvakAangifte"/>
      </TijdvakAangifteId>
      <xsl:next-match/>
  </xsl:template>


will add the new element before the "Date" (which will itself simply be copied by relying on "next-match" which uses the built-in copy declared with the "mode" already).

So the complete stylesheet uses

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xpath-default-namespace="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   xmlns="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   exclude-result-prefixes="#all"
   version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>
 
  <xsl:template match="TijdvakAangifte/Date">
      <TijdvakAangifteId>
          <xsl:number count="TijdvakAangifte"/>
      </TijdvakAangifteId>
      <xsl:next-match/>
  </xsl:template>
 
</xsl:stylesheet>


You will need to adjust the "ID" computation where I simply count the parent of the "Date" as needed as you haven't really explained what kind of id you are looking for.

Code: Select all

  <xsl:template match="TijdvakAangifte/Date">
      <TijdvakAangifteId>
          <xsl:value-of select="generate-id()"/>
      </TijdvakAangifteId>
      <xsl:next-match/>
  </xsl:template>


for instance would give you whatever the XSLT processor generates for the matched "Date" element.
HuubT
Posts: 4

Re: XSLT: Generate ID

Fri Sep 14, 2018 9:11 pm

Thanks for your support; it helped me a lot.
HuubT
Posts: 4

Re: XSLT: Generate ID

Sat Sep 15, 2018 10:08 am

Martin Honnen wrote:So what kind of ID are you looking for?

In general assuming you have a version of oXygen that supports XSLT 3 all such stylesheet that need to perform a transformation of some nodes but keep the rest of the document unchanged would start with

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   exclude-result-prefixes="#all"
   version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>
 
</xsl:stylesheet>


then, as your input elements are in a certain namespace and you want to match them you would declare that namespace as the xpath-default-namespace with e.g.

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xpath-default-namespace="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   exclude-result-prefixes="#all"
   version="3.0">


and as you also want to create new elements in your XSLT declare the namespace there as the default namespace

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xpath-default-namespace="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   xmlns="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   exclude-result-prefixes="#all"
   version="3.0">


and now you are ready to write template for those elements you want to transform/change so you want e.g.

Code: Select all

  <xsl:template match="TijdvakAangifte/Date">
      <TijdvakAangifteId>
          <xsl:number count="TijdvakAangifte"/>
      </TijdvakAangifteId>
      <xsl:next-match/>
  </xsl:template>


will add the new element before the "Date" (which will itself simply be copied by relying on "next-match" which uses the built-in copy declared with the "mode" already).

So the complete stylesheet uses

Code: Select all

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xpath-default-namespace="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   xmlns="http://xml.belastingdienst.nl/schemas/Loonaangifte/2018/01"
   exclude-result-prefixes="#all"
   version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>
 
  <xsl:template match="TijdvakAangifte/Date">
      <TijdvakAangifteId>
          <xsl:number count="TijdvakAangifte"/>
      </TijdvakAangifteId>
      <xsl:next-match/>
  </xsl:template>
 
</xsl:stylesheet>


You will need to adjust the "ID" computation where I simply count the parent of the "Date" as needed as you haven't really explained what kind of id you are looking for.

Code: Select all

  <xsl:template match="TijdvakAangifte/Date">
      <TijdvakAangifteId>
          <xsl:value-of select="generate-id()"/>
      </TijdvakAangifteId>
      <xsl:next-match/>
  </xsl:template>


for instance would give you whatever the XSLT processor generates for the matched "Date" element.


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hello Martin,

Thanks for your input.
I have another question. Is it possible to inject a parent id (based on number count) into a child section?
Like this:
<Root>
<LevelA>
<LevelAId>1</LevelAId>
<LevelAName>xxxxxx<//LevelAName>
<LevelB>
<LevelBId>1</LevelBId>
<LevelAId>1</LevelAId>
<LevelBName>yyyyy</LevelBName>
</LevelB>
</LevelA>
etc.
<?Root>

Would help me a lot!

With kind regards,

HuubT
HuubT
Posts: 4

Re: XSLT: Generate ID

Sat Sep 15, 2018 12:02 pm

Hello Martin,

Thanks for your input.
I have another question regarding parent-child relationships.

How can I achieve the injection of <ParenId> in <Parent> and <Child> sections in the example below?

<Root>
<Parent>
<ParentId>1</ParentId>
<ParentName>P1</ParentName>
<Child>
<ChildId>1</ChildId>
<ParentId>1</ParentId>
<ChildName>C1</ChildName>
</Child>
<Child>
<ChildId>2</ChildId>
<ParentId>1</ParentId>
<ChildName>C2</ChildName>
</Child>
</Parent>
etc.
</Root>

Thanks for your answer.

With kind regards,

HuubT
Martin Honnen
Posts: 43

Re: XSLT: Generate ID

Mon Sep 17, 2018 11:08 pm

HuubT wrote:I have another question regarding parent-child relationships.

How can I achieve the injection of <ParenId> in <Parent> and <Child> sections in the example below?

<Root>
<Parent>
<ParentId>1</ParentId>
<ParentName>P1</ParentName>
<Child>
<ChildId>1</ChildId>
<ParentId>1</ParentId>
<ChildName>C1</ChildName>
</Child>
<Child>
<ChildId>2</ChildId>
<ParentId>1</ParentId>
<ChildName>C2</ChildName>
</Child>
</Parent>
etc.
</Root>



Consider to ask a new question in a separate question, in general you can use the `xsl:number` https://www.w3.org/TR/xslt-30/#number element quite well to compute such numbers by using an appropriate pattern, if that is what you are looking for. If the "ParentId" is already in the "Parent" element and you simply want to copy it to the "ParentId" of the child you would navigate up e.g.

Code: Select all

<xsl:template match="Child">
  <xsl:copy>
    <xsl:copy-of select="ChildId, ../ParentId, ChildName"/>
  </xsl:copy>
</xsl:template>

Return to “XSLT and FOP”

Who is online

Users browsing this forum: No registered users and 0 guests