nanobug62
nanobug62

Reputation: 3

How to merge two xml files using xslt generating text output

I already saw variants of my problem under how-to-merge-two-xml-files-with-xslt or how-can-i-merge-these-two-xml-files-using-xslt , but these examples do not handle the text-output and also not handle a static refernece to'default.xml'.

I am trying to generate a C headerfile beeing generated from a defaults.xml that gets amended by an target.xml.

I am using xsltproc as xslt processor and would like to be able to do xslproc merg.xsl target1.xml > target1.h.

Meaning to have one defaults.xml file and different target.xml files

example defaults.xml:

<?xml version="1.0" encoding="UTF-8"?>

<defaults>
<ConfigParam name="F_SAMPLE_STRING">
  <value>{1,0,0}</value>
</ConfigParam>

<ConfigParam name="F_SAMPLE_INT">
  <value>40</value>
</ConfigParam>

<ConfigParam name="F_SAMPLE_X">
  <value>TRUE_DEF</value>
</ConfigParam>

</defaults>
and a sample target1.xml

<?xml version="1.0" encoding="UTF-8"?>
<Override>
		<ConfigParam name="F_SAMPLE_STRING">
		  <value>"hallo"</value>
		</ConfigParam>

		<ConfigParam name="F_SAMPLE_Y">
		  <value>TRUE</value>
		</ConfigParam>
</Override>

My own starting xslt looks like this, but does lack the merging/amendment part

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text"/> 
<xsl:param name="fileName" select=" 'defaults.xml' " />
<xsl:param name="defaults" select="document($fileName)" />
<xsl:variable name="defaultParams" select="$defaults//ConfigParam" />


  <xsl:template match="@* | node() ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  
  
  <xsl:template match="ConfigParam">
  #define <xsl:value-of select="@name"/><xsl:text> </xsl:text><xsl:value-of select="value"/>    <xsl:text>&#xd;&#xa;</xsl:text> 
  </xsl:template>

</xsl:stylesheet>

The other examples I saw use a static target.xml or use both files (target/defaults) from static locations. They also do not output text but xml. I am new to xslt and can not come up with a good merging identity pattern. Please help.

Upvotes: 0

Views: 318

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

If I understand correctly, you want to do:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/>

<xsl:param name="path-to-defaults" select="'defaults.xml'" />
<xsl:variable name="defaults" select="document($path-to-defaults)/defaults/ConfigParam" />
<xsl:variable name="overrides" select="/Override/ConfigParam" />

<xsl:template match="/">
    <xsl:apply-templates select="$defaults[not(@name = $overrides/@name)]" />
    <xsl:apply-templates select="$overrides" />
</xsl:template>     

<xsl:template match="ConfigParam">
    <xsl:text>#define </xsl:text>
    <xsl:value-of select="@name"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="value"/>
    <xsl:text>&#xd;&#xa;</xsl:text> 
</xsl:template>  

</xsl:stylesheet>

This assumes you will be processing the target1.xml file and pointing to a constant defaults.xml file. The result here is:

#define F_SAMPLE_INT 40
#define F_SAMPLE_X TRUE_DEF
#define F_SAMPLE_STRING "hallo"
#define F_SAMPLE_Y TRUE

Note: with a text output, you don't want to use the identity transform template.

Upvotes: 1

Related Questions