2

I have an XML, something like this:

 <?xml version="1.0" encoding="UTF-8"?>
       <earth>
     <computer>
            <parts>
                <cpu>AMD;fast</cpu>
                <video>GF</video>
                <power>slow</power>
                ...others
            </parts>
            <owner>
             <name>Frank</name>
            <owner>
          </computer>

    <earth>

I want create xsl transform (xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"). My expected result only if cpu have sign ';' - power should be change to value after ';', if there will not be ';' result should no change

<earth>
 <computer>
        <parts>
            <cpu>AMD</cpu>
            <video>GF</video>
            <power>fast</power>
            ...others
        </parts>
        <owner>
          <name>Frank</name>
        <owner>
      </computer>
<earth>

Try to do something like this but no luck:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions"
    exclude-result-prefixes="fn">
    <xsl:output encoding="utf-8" method="xml" indent="yes" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="parts">
        <xsl:choose>
            <!-- try test if node name equals 'power' if equals them try make logic 
                here, this dont work-->
            <xsl:when test="name() = 'power'">
                <xsl:variable name="text" select="./cpu" />
                <xsl:variable name="sep" select="';'" />
                <xsl:variable name="powerTable" select="tokenize($text, $sep)" />
                <xsl:value-of select="$powerTable[1]" />
            </xsl:when>
            <!--if not 'power' copy node -->
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@* | node()" />
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
4
  • 1
    "I have an XML stylesheet". May we know how does it looks like? Because the ones posted so far are just the XMLs Commented Apr 17, 2016 at 7:05
  • I edit my post, I have xml file and need create xsl to transform this file to new xml file with expected result Commented Apr 17, 2016 at 7:44
  • Have you attempted to write the XSLT so far? If you have, please share it and explain which part is not working as expected or which part you have no idea how to implement. If you haven't, please read introductory tutorials on XSLT, and try to write one on your own first. Good luck! Commented Apr 17, 2016 at 8:20
  • 1
    Thx for reply, I create template for parts, try to test there if node name equals power, but this dont work. All others node should be copy Commented Apr 17, 2016 at 8:46

1 Answer 1

0

I would use the following templates to accomplish this :

<xsl:template match="parts[contains(cpu,';')]/power">
    <power>
        <xsl:value-of select="../cpu/substring-after(.,';')"/>
    </power>
</xsl:template>

<xsl:template match="cpu[contains(.,';')]">
    <cpu>
        <xsl:value-of select="substring-before(.,';')"/>
    </cpu>
</xsl:template>

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

The first template matches power element that is direct child of parts (parts/power), where the parts has child element cpu that contains character ; (parts[contains(cpu,';')]). This template will output power element with the value from cpu element value, after character ;.

The second template, matches cpu element that contains character ;, and outputs cpu element with the initial value, before character ;.

The other template is just identity template which I assume you knew the purpose.

Sign up to request clarification or add additional context in comments.

Comments

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.