0

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.

2

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thx, alot. Exactly what I wanted. The selective apply of templates to the node-sets and the setup of node-sets are the eye-openers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.