简体   繁体   中英

Data driven XML generation using XSLT

For one of my projects I have a XML file containing templates, that should generate plots for a GUI. The user can write its own XML templates and apply it to the currently load data.

The simplified XML template file looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<Templates>
  <Template name="template">
    <PlotWindow name="PlotWindow">
      <Title>My title</Title>
      <For>
        <Var>%Variable%</Var>
        <Plot name="%Variable%">
          <Item>f(%Variable%)</Item>
        </Plot>
      </For>
    </PlotWindow>
  </Template>
</Templates>

The For -tag should be replaced by all the data contained in %Variable% . The data itself is defined in a second XML file.

<?xml version="1.0" encoding="utf-8"?>
<Data>
  <Var name="%Variable%">
    <Item>Test</Item>
    <Item>MyVar</Item>
    <Item>ABC</Item>
  </Var>
</Data>

%Variable% should be iterated through Test , MyVar and ABC . The desired output should be a third XML file shown below:

<?xml version="1.0" encoding="utf-8"?>
<Result>
  <PlotWindow name="PlotWindow">
    <Title>My title</Title>
    <Plot name="Test">
      <Item>f(Test)</Item>
    </Plot>
    <Plot name="MyVar">
      <Item>f(MyVar)</Item>
    </Plot>
    <Plot name="ABC">
      <Item>f(ABC)</Item>
    </Plot>
  </PlotWindow>
</Result>

It should be possible to get such a result by some kind of XSLT file.

What will this file look like?

I'm not sure how detailed your examples are (can there be multiple Var elements in Data ? Multiple For elements in PlotWindow ?), but given the current content this can be a solution.

Assuming the XML looks like:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <Data>
        <Var name="%Variable%">
            <Item>Test</Item>
            <Item>MyVar</Item>
            <Item>ABC</Item>
        </Var>
    </Data>
    <Templates>
        <Template name="template">
            <PlotWindow name="PlotWindow">
                <Title>My title</Title>
                <For>
                    <Var>%Variable%</Var>
                    <Plot name="%Variable%">
                        <Item>f(%Variable%)</Item>
                    </Plot>
                </For>
            </PlotWindow>
        </Template>
    </Templates>
</root>

(I guess the Data is in a different file. If so, use document() function to load it at the line <xsl:for-each select="//Data"> .)

XSL:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml"  />

    <xsl:template match="Templates">
        <Result>
            <xsl:apply-templates/>
        </Result>
    </xsl:template>

    <xsl:template match="PlotWindow|Title">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="For">
        <xsl:variable name="name" select="./Var/text()"/>

        <xsl:for-each select="//Data">
                <xsl:for-each select="Var[@name=$name]">
                    <xsl:for-each select="Item">
                        <xsl:variable name="plotname" select="./text()"/>
                        <Plot name="{$plotname}">
                            <Item>f(<xsl:value-of select="$plotname"/>)</Item>
                        </Plot>
                    </xsl:for-each>
                </xsl:for-each>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="Data|Var|Item"></xsl:template>

</xsl:stylesheet>

Result:

<?xml version="1.0" encoding="UTF-8"?>
<Result>
    <PlotWindow name="PlotWindow">
        <Title>My title</Title>
        <Plot name="Test">
            <Item>f(Test)</Item>
        </Plot>
        <Plot name="MyVar">
            <Item>f(MyVar)</Item>
        </Plot>
        <Plot name="ABC">
            <Item>f(ABC)</Item>
        </Plot>
    </PlotWindow>
</Result>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM