Transformeer tagwaarde naar tagnaam (XSL)

Uit De Vliegende Brigade
Ga naar: navigatie, zoeken

Het probleem

In bestand

<?xml version="1.0"?>
<Items>
	<Item><Item_code>00000001</Item_code><Item_type>S</Item_type>
		<Description>Dinges_01</Description>
		<FreeFields>
  			<FreeTexts>
				<FreeText><FreeText_number>1</FreeText_number></FreeText>
				<FreeText><FreeText_number>2</FreeText_number>Veld_02</FreeText>
				<FreeText><FreeText_number>3</FreeText_number>Veld_03</FreeText>
				<FreeText><FreeText_number>4</FreeText_number></FreeText>
			</FreeTexts>
		</FreeFields>
	</Item>

	<Item><Item_code>00000002</Item_code><Item_type>S</Item_type>
		<Description>Widget_01</Description>
		<FreeFields>
  			<FreeTexts>
				<FreeText><FreeText_number>1</FreeText_number></FreeText>
				<FreeText><FreeText_number>2</FreeText_number>Field_02</FreeText>
				<FreeText><FreeText_number>3</FreeText_number>Field_03</FreeText>
				<FreeText><FreeText_number>4</FreeText_number></FreeText>
			</FreeTexts>
		</FreeFields>
	</Item>	
</Items>

wil ik

<FreeText><FreeText_number>1</FreeText_number></FreeText>
<FreeText><FreeText_number>2</FreeText_number>Veld_02</FreeText>
<FreeText><FreeText_number>3</FreeText_number>Veld_03</FreeText>
<FreeText><FreeText_number>4</FreeText_number></FreeText>

omfietsen naar

<FreeText><FreeText_number_1>1</FreeText_number_1></FreeText>
<FreeText><FreeText_number_2>2</FreeText_number_2>Veld_02</FreeText>
<FreeText><FreeText_number_3>3</FreeText_number_3>Veld_03</FreeText>
<FreeText><FreeText_number_4>4</FreeText_number_4></FreeText>

en uiteindelijk naar

<FreeText_number_1>       </FreeText_number_1>
<FreeText_number_2>Veld_02</FreeText_number_2>
<FreeText_number_3>Veld_03</FreeText>
<FreeText_number_4>       </FreeText_number_4>

De oplossing

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />


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


<!-- =========================================== -->
<!-- Alle attributen omfietsen naar subelementen -->
<!-- =========================================== -->


<!-- Limited template to "FreeText" nodes      -->
<!-- =========================================== -->
<!--                                             -->
<xsl:template match="FreeText">


	<!-- Initiate variables                          -->
	<!-- =========================================== -->
	<!--                                             -->
  	<xsl:variable name="veld_nummer" select="FreeText_number" />

  	<!-- <xsl:variable name="veld_waarde" select="FreeText" /> -->


	<!-- Dynamically create element                  -->
	<!-- =========================================== -->
	<!--                                             -->
  	<!--											 -->
  	<xsl:element name="freetext_{$veld_nummer}">

  		<!-- Waarde vd. node ZONDER subnode -->

		<xsl:value-of select="./text()"/>
  
        </xsl:element>


<!-- Close template                              -->
<!--                                             -->
</xsl:template>


</xsl:stylesheet>

Voorbeeld Stack Overflow

[1]:

XML - invoer

<Policy>
    <Attributes>
        <AttributeName>is_policy_loan</AttributeName>
        <AttributeValue>Yes</AttributeValue>
    </Attributes>
    <Attributes>
        <AttributeName>is_policy_owners</AttributeName>
        <AttributeValue>Yes</AttributeValue>
    </Attributes>       
    <Attributes>
        <AttributeName>is_policy_twoyears</AttributeName>
        <AttributeValue>Yes</AttributeValue>
    </Attributes>       
</Policy>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />


<!-- =========================================== -->
<!-- Identity Transformation                     -->
<!-- =========================================== -->
<!--                                             -->
<!-- Looks a bit strange, but probably is the    -->
<!-- exact same: All data is being copied        -->

<xsl:template match="Policy">
  <xsl:element name="Policy">
     <xsl:apply-templates />
  </xsl:element>
</xsl:template>


<!-- =========================================== -->
<!-- Alle attributen omfietsen naar subelementen -->
<!-- =========================================== -->


<!-- Limited template to "Attributes" nodes      -->
<!-- =========================================== -->
<!--                                             -->
<xsl:template match="Attributes">


	<!-- Initiate variable "name"                    -->
	<!-- =========================================== -->
	<!--                                             -->
	<!-- * https://www.w3schools.com/xml/ref_xsl_el_variable.asp -->
	<!-- * Within <Attributes>, there is only one    -->
	<!--   field <AttributeValue>                    -->
	<!--                                             -->
  	<xsl:variable name="name" select="AttributeName" />



	<!-- Dynamically create element                  -->
	<!-- =========================================== -->
	<!--                                             -->
	<!-- * https://www.w3schools.com/xml/ref_xsl_el_element.asp -->
	<!--                                             -->
        <xsl:element name="{$name}">

	<!-- Here's the value of the other field fetched -->
	<!--                                             -->
	<xsl:value-of select="AttributeValue" />
  
  </xsl:element>


<!-- Close template                              -->
<!--                                             -->
</xsl:template>


</xsl:stylesheet>

Selecteer node-waarde zonder subnode

In de voorbeelddata wil ik de waarde van FreeText hebben, zonder de waarde van de subnodes (FreeText_number). Dat doe je zo:

<!-- Limited template to "FreeText" nodes      -->
<!-- =========================================== -->
<!--                                             -->
<xsl:template match="FreeText">


	<!-- Initiate variables                          -->
	<!-- =========================================== -->
	<!--                                             -->
  	<xsl:variable name="veld_nummer" select="FreeText_number" />
  	<xsl:variable name="veld_waarde" select="FreeText" />


	<!-- Dynamically create element                  -->
	<!-- =========================================== -->
	<!--                                             -->
  	<!--
  	<xsl:element name="freetext_{$veld_nummer}">

		<xsl:value-of select="." />
  
  </xsl:element>

	-->

	<!-- Test: Try to get the value              -->
	<!-- =========================================== -->
	<!--                                             -->
	Name <xsl:value-of select="@name"/>
	Value <xsl:value-of select="@value"/>
	Text <xsl:value-of select="@text()"/>
	Punt <xsl:value-of select="."/>
	Punt <xsl:value-of select="./text()"/>   ← DIT IS 'M!

<!-- Close template                              -->
<!--                                             -->
</xsl:template>


Bronnen