Xslt <key use = "position ()" .. / "> problem
I have (very large tables, for example ...) xml data from which I have to create a more readable one.
I have headings at the top of the structure and would like to create elementsfrom their text value and apply them to the rest of the document.
The evidence probably speaks more clearly, so my input document looks like
<?xml version="1.0"?>
<root>
<headers>
<header>line</header>
<header>product</header>
<header>order</header>
<header>qty</header>
<header>deadline</header>
</headers>
<row>
<data>2</data>
<data>HU12_SETUP</data>
<data>16069061</data>
<data>1</data>
<data>2011-04-13T09:22:59.980</data>
</row>
<row>
<data>1</data>
<data>40PFL7605H/12</data>
<data>16310360</data>
<data>200</data>
<data>2011-04-13T09:22:59.980</data>
</row>
</root>
and my goal is to have an XML document like:
<?xml version="1.0"?>
<morning>
<row>
<line>2</line>
<product>HU12_SETUP</product>
<order>16069061</order>
<qty>1</qty>
<deadline>0</deadline>
</row>
<row>
<line>1</line>
<product>40PFL7605H/12</product>
<order>16310360</order>
<qty>200</qty>
<deadline>77</deadline>
</row>
</morning>
"" / "" , , , .
, key data header , - ( ~ X().
, xsl, / - key, .
() xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="header" match="header" use="position()" />
<xsl:template match="/">
<morning>
<xsl:apply-templates />
</morning>
</xsl:template>
<xsl:template match="headers" />
<xsl:template match="row">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:element name="{concat('bla-',position())}">
<xsl:value-of select="key('header',position())" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
, () .
, .
1.0:
<?xml version='1.0' encoding='UTF-8' ?>
<morning>
<row>
<bla-1>line</bla-1>
<bla-2/>
<bla-3/>
<bla-4/>
<bla-5/>
</row>
<row>
<bla-1>line</bla-1>
<bla-2/>
<bla-3/>
<bla-4/>
<bla-5/>
</row>
</morning>
2.0:
<?xml version='1.0' encoding='UTF-8' ?>
<morning>
<row>
<bla-1>line product order qty deadline</bla-1>
<bla-2/>
<bla-3/>
<bla-4/>
<bla-5/>
</row>
<row>
<bla-1>line product order qty deadline</bla-1>
<bla-2/>
<bla-3/>
<bla-4/>
<bla-5/>
</row>
</morning>
, key('header',position()) , ( , ).
, !
:
@LarsH @Alejandro ( key), :
<xsl:template match="data">
<xsl:variable name="posn" select="position()" />
<xsl:element name="{key('header',1)[$posn]}" />
<xsl:element name="{key('header',1)[position()]}" />
</xsl:template>
, 1 , , ?
, line, lineproductorderqtydeadline .
- ?
XSLT 1.0 2.0 , 1.0, xsl:value-of node , (IIRC) 2.0, , . ( , .)
, , , header 1. , position() use ( , ), .
, position(), - :
<xsl:key name="header" match="header"
use="count(preceding-sibling::header) + 1" />
. , , , .
,
<xsl:template match="data">
<xsl:variable name="posn" value="position()" />
<xsl:element name="{concat('bla-', $posn)}">
<xsl:value-of select="/root/headers/header[$posn]" />
</xsl:element>
</xsl:template>
, , - [$posn].
:
"" , , . :
<xsl:template match="data">
<xsl:variable name="posn" select="position()" />
<xsl:element name="{key('header',1)[$posn]}" />
<xsl:element name="{key('header',1)[position()]}" />
, node, node . position(), node data, row. , position() node (a data) . $posn.
key('header',1) node header , : header 1. , key('header',1)[$posn] n th header, n - .
position(): node node, XPath , node node. , key('header',1)[...] node - node, key('header',1). , header. header position() .
... , e , position() = e. ,
<xsl:element name="{key('header',1)[position() = position()]}" />
position() = position() ,
<xsl:element name="{key('header',1)}" />
.
, node x y z ,
xsl:key, :
x
matchxsl:key
namexsl:key;,
usexsl:keyx node node x node, u, z u ,stringu node -set, z u.
, position() use 1.
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:variable name="vHeaders" select="/root/headers/header"/>
<xsl:template match="/">
<morning>
<xsl:apply-templates />
</morning>
</xsl:template>
<xsl:template match="headers" />
<xsl:template match="row">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:variable name="vPosition" select="position()"/>
<xsl:element name="{$vHeaders[$vPosition]}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
:
<morning>
<row>
<line>2</line>
<product>HU12_SETUP</product>
<order>16069061</order>
<qty>1</qty>
<deadline>2011-04-13T09:22:59.980</deadline>
</row>
<row>
<line>1</line>
<product>40PFL7605H/12</product>
<order>16310360</order>
<qty>200</qty>
<deadline>2011-04-13T09:22:59.980</deadline>
</row>
</morning>