开发者

Apply template to nodes that have children with attribute

I'd like to apply a template to nodes that have children with a specified attribute, and I'm curious if it's possible with a <template match=...

So if i have an input xml

<?xml version="1.0"?>
<parent-node>
    <child-node>
        <label>value1</label>
        <name>name1</name>
        <desc src="anything">description1</desc&开发者_JS百科gt;
    </child-node>
    <child-node>
        <label>value2</label>
        <desc>description2</desc>
    </child-node>
    <some-node>
        <name>name3</name>
        <desc src="something">description3</desc>
    </some-node>
</parent-node>

the required template will be applied to the nodes that have desc children with src attribute defined, eg. the first and last nodes:

<child-node>
    <label>value1</label>
    <name>name1</name>
    <desc src="anything">description1</desc>
</child-node>
<some-node>
    <name>name3</name>
    <desc src="something">description3</desc>
</some-node>

The best i have so far is a template matching the nodes that have desc children, and the rest (testing if any of the desc nodes have @src) is inside the template, in an xsl:choose clause:

<xsl:template match="*[desc]">
    <xsl:choose>
        <xsl:when test="desc[@src]">
            <xsl:element name="node-with-src">
                [...]
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="node">
                [...]
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

By having such a template, i could leave but the otherwise part inside this template, and anyway, it would be a lot nicer.

Thank you in advance for every answer!

Edit I'd prefer a 1.0 solution, but it's not a criteria.


More complex (nested) predicates are allowed. Use this:

<xsl:template match="*[desc[@src]]">

And a corresponding template for the nodes without a src attribute:

<xsl:template match="*[desc[not(@src)]]">

For example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="*[desc[@src]]"> 
        <xsl:element name="node-with-src"/>
    </xsl:template>
    <xsl:template match="*[desc[not(@src)]]">
        <xsl:element name="node"/>
    </xsl:template>
</xsl:stylesheet>

Applied to:

<parent-node>
    <child-node>
        <label>value1</label>
        <name>name1</name>
        <desc src="anything">description1</desc>
    </child-node>
    <child-node>
        <label>value2</label>
        <desc>description2</desc>
    </child-node>
    <some-node>
        <name>name3</name>
        <desc src="something">description3</desc>
    </some-node>
</parent-node>

Output:

<node-with-src/>
<node/>
<node-with-src/>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜