Search code examples
xmlxslt

conditionally copy XML elements using XSLT with extra namespace?


I have an XML beginning with these lines

<?xml version="1.0" encoding="utf-8"?>
<TRANSFER xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.interlis.ch/INTERLIS2.3" xmlns="http://www.interlis.ch/INTERLIS2.3">
  <HEADERSECTION VERSION="2.3" SENDER="ACME">
    <MODELS>
      <MODEL NAME="DSS_2015_LV95" VERSION="13.11.2018" URI="http://www.vsa.ch/models" />
    </MODELS>
  </HEADERSECTION>
  <DATASECTION>
    <DSS_2015_LV95.Siedlungsentwaesserung BID="999">
      <DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_123>
        <TextPos>
          <COORD>
      .....
      <DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_123>
        <TextPos>
          <COORD>
      .....
      <DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_456>
        <Value>
          <Price>
      .....
      <DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_789>
        <Text>
          <Cost>
      .....

I found a lot of examples (and also one which helped me with my special namespace..) to "copy everything but ....123":

  • make a template which copies everything
  • add a second template which ignores "...123"

But now I have the opposite task to "copy only ...123" incl. header and consider the namespace. The way described above - "copy everything but 456 and 789" - can not be used, because I don't know what to be ignored.

I don't show the codes I tried (based on xsl:copy ..) because it is a confusing collection of trash, but I messed something up match and select..

I hope my description is understandable - sorry for my unprofessional knowledge, and many thanks in advance.


Solution

  • Based on your latest comment you might want something like

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0"
      xmlns:il="http://www.interlis.ch/INTERLIS2.3">
      
      <xsl:template match="il:DATASECTION//node()[not(descendant-or-self::il:DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_123|ancestor::il:DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_123)]"/> 
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    What is not specified is whether you want an empty DATASECTION to be copied to the output if there are no DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_123 at all or whether in that case the DATASECTION element should not appear in the output. The code as posted would create an empty DATASECTION if there are no DSS_2015_LV95.Siedlungsentwaesserung.Abwasserbauwerk_Text_123 children or descendants.