0

as I already mentioned in the thread title, i would like to remove an node or element, depending on value of another element in same level.

To prevent an duplicate tag, the problem is not to remove an element or node from xml, rather to remove node or element dependig of value from another element in same sub-node/level.

to discribe this i've build an example structure with random sample data.

<ROOT>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>UNNEEDED</TYPE>
            <VALUE>remove this</VALUE>
            <NAME> but this requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <SOMEWHERE>
        <OTHERWHERE>
            <TYPE>UNNEEDED</TYPE>
            <VALUE>but do not remove</VALUE>
            <NAME>also requiered</NAME>
        </OTHERWHERE>
    </SOMEWHERE>
</ROOT>

Now i need an xsl transformation that remove the node VALUE if text-value of type, in the same node, is "UNNEEDED".

The inpur parameter for this transformation looking like that if:/ROOT/DETAILS/ALLOC/TYPE=UNNEEDED then remove: /ROOT/DETAILS/ALLOC/VALUE

It could be that multiple removes are defined, so i have to remove one or more elements.

if:/ROOT/DETAILS/ALLOC/TYPE=UNNEEDED then remove: /ROOT/DETAILS/ALLOC/VALUE; /ROOT/DETAILS/ALLOC/otherElement;

+The search string "UNNEEDED" is exemplary and can be anything (names, descriptions, identifiers)

To remove the node by an simple xpath expresion, the node value remove on all node. remove the node by index it's not possible. I habe to transform an dynamically xml strcture. The structure can contains this values but not must be.

So the desired output is

<ROOT>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>UNNEEDED</TYPE>
            - - - - - - - - - - -
            <NAME> but this requiered</NAME>
        </ALLOC>
    </DETAILS>
    <DETAILS>
        <ALLOC>
            <TYPE>NEEDED</TYPE>
            <VALUE>do not remove</VALUE>
            <NAME>also requiered</NAME>
        </ALLOC>
    </DETAILS>
    <SOMEWHERE>
        <OTHERWHERE>
            <TYPE>UNNEEDED</TYPE>
            <VALUE>but do not remove</VALUE>
            <NAME>also requiered</NAME>
        </OTHERWHERE>
    </SOMEWHERE>
</ROOT>

[Only the Element 'Value' in XPATH: /ROOT/DETAILS/ALLOC must be removed, but not the element 'Value' in XPATH /ROOT/SOMEWHERE/OTHERWHERE]

Remove the node by an indexless xpath expression, removes the node VALUE all sub-nodes on this xpath Remove the node by an index xpath expression is also not possible, because i do not know the index before. The given xpath expression is indexless and i have to check if text-value of type is 'something' and then remove node 'value'.

I have to solute this problem only via xml and xslt.

I would like to thank you in advance.

1 Answer 1

2

Try it this way:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="VALUE[../TYPE='UNNEEDED']"/>

</xsl:stylesheet>

Added:

To restrict the removal only to VALUE nodes that are children of ALLOC, use:

<xsl:template match="ALLOC[TYPE='UNNEEDED']/VALUE"/>
Sign up to request clarification or add additional context in comments.

6 Comments

thanks for this idea michael.hor257k. I tried this way also. It will works, but the problem is the relative path of element. it could be that relative path could found otherwhere and will also modify this node.
@Hans.Olo, your comment is little unclear. May be a sample would help.
@Hans.Olo This will remove VALUE if it has a sibling TYPE with a value of "UNNEEDED". If by "in same level" you meant something else, you need to clarify.
Good Morning Guys, i've edited the question and tried to explain it a little better. I hope it is now more understandable.
I could solve the problem by yours approach, it was relatively simple. I thought already too complicated. <xsl:template match="/ROOT/DETAILS/ALLOC/VALUE[../TYPE='UNNEEDED']"/>
|

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.