Search code examples
xmlxsltxpathnodessiblings

make changes to nodes between other sibling nodes in XSLT


I am a beginner to xslt and would very much appreciate your help for the below-mentioned issue. Inside node <case>, I want to select <s> nodes between its first <beginning> and first <end> sibling nodes , the second <beginning> and the second <end> and respectively the nth beginning and the nth node; and add the attribute @attribute:unsolved to them. Meanwhile, I want to keep the rest of the xml file intact. My input and desired output are shown below. Thanks a lot for your help.

XML INPUT:

<content>
    <issue>1</issue>
    <status>to be solved</status>
</content> 
<case>
    <beginning>problem</beginning>
    <s>this</s>
    <s>is</s>
    <s>a</s>
    <s>problem</s>
    <end>problem</end>
    <s>no</s>
    <s>problem</s>
    <s>here</s>
    <s>.</s>
    <beginning>problem</beginning>
    <s>problem</s>
    <s>again</s>
    <end>problem</end>
    <s>no</s>
    <s>issue</s>
</case>

Desired output:

<content>
    <issue>1</issue>
    <status>to be solved</status>
</content>
<case>
    <beginning>problem</beginning>
    <s attribute='unsolved'>this</s>
    <s attribute='unsolved'>is</s>
    <s attribute='unsolved'>a</s>
    <s attribute='unsolved'>problem</s>
    <end>problem</end>
    <s>no</s>
    <s>problem</s>
    <s>here</s>
    <s>.</s>
    <beginning>problem</beginning>
    <s attribute='unsolved'>problem</s>
    <s attribute='unsolved'>again</s>
    <end>problem</end>
    <s>no</s>
    <s>issue</s>
</case>

Solution

  • If I understand what you mean, then your XPath will be show like:

    `//beginning/following::s[./following::end]
    [
    count(.|//end/following::s[./following::beginning])
    !=
    count(//end/following::s[./following::beginning])
    ]`
    

    Please see this is picture