We have an XML format that is actually just HTML with some extra gubbins. It defines which HTML elements are editable, and which attributes are editable thereof.
Here's an example
<img src="images/placeholder.jpg"
alt="Placeholder"
width="600"
height="250"
border="0">
<var attr="src" />
<var attr="height" ok="150-300" />
</img>
The XML is so the templates are easier to write but I need to convert it to valid(ish) HTML. To do this I want to collapse it into:
<img src="images/placeholder.jpg"
alt="Placeholder"
width="600"
height="250"
border="0"
editable="src height"
constraints="height:150-300">
I can do this for <img>
, but the problem is that the <var>
tags can actually appear as a child of any element in the page. In all cases the algorithm for converting it to attributes is the same but what I can't work out how to do is specify an XSLT template that can match the parent element of a <var>
tag. I tried match="var/.."
but this turned out to be invalid.
The alternative would be to match the <var>
s and add them as attributes to their parents, but I believe that at this point in the processing that particular ship would already have sailed.
Is this doable?
Thankies
Answer!
I combined the more complete answer with Dimitre's usefully accurate answer to form the following:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="*[var]">
<xsl:copy >
<xsl:attribute name="editable">
<xsl:for-each select="var[@attr]">
<xsl:value-of
select="concat(@attr,
substring(' ',
1 div (position()!=last())))"/>
</xsl:for-each>
</xsl:attribute>
<xsl:attribute name="constraints">
<xsl:for-each select="var[@ok]">
<xsl:value-of
select="concat(@attr,':',@ok,
substring(';',
1 div (position()!=last())))"/>
</xsl:for-each>
</xsl:attribute>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="var">
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Unfortunately the exact answer Alejandro gave didn't work straight away (still not sure why),but this combination of his answer and Dmitri's answer seems to have done the job nicely :)
what I can't work out how to do is specify an XSLT template that can match the parent element of a
<var>
tag
Use :
<xsl:template match="*[var]">
我将考虑在解析器到达<img>
标记并在该变量内显式构造一个新的<img ...>
,构造一个局部变量( <xsl:variable>
),遍历它找到的所有<var>
子元素( <xsl:foreach ...>
有人吗?)在耗尽后关闭变量...然后将变量写出来?
Besides Dimitre's exact answer to your question, other approach would be:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|var"/>
<xsl:apply-templates select="node()[not(self::var)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="var"/>
<xsl:template match="var[1]">
<xsl:attribute name="editable">
<xsl:for-each select="../var/@attr">
<xsl:value-of
select="concat(.,
substring(' ',
1 div (position()!=last())))"/>
</xsl:for-each>
</xsl:attribute>
<xsl:attribute name="constraints">
<xsl:for-each select="../var/@ok">
<xsl:value-of
select="concat(../@attr,':',.,
substring(';',
1 div (position()!=last())))"/>
</xsl:for-each>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Output:
<img src="images/placeholder.jpg"
alt="Placeholder"
width="600"
height="250"
border="0"
editable="src height"
constraints="height:150-300"></img>
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.