-2

I was trying to see if the input objectType, value0 exists in the Types/Type and check the condition to use the sibling attribute name value of the Types/Type in the output xml. Here is the input xml:

<?xml version="1.0" encoding="UTF-8"?>
<outPut>
  <object>
    <objectType>TestOne</objectType>
    <Attributes>
      <attribute name="value0">codeOne</attribute>
      <attribute name="value1">35</attribute>
      <attribute name="value2">35</attribute>
    </Attributes>
    <objectType>TestTwo</objectType>
    <Attributes>
      <attribute name="value0">codeTwo</attribute>
      <attribute name="value1">25</attribute>
      <attribute name="value2">35</attribute>
    </Attributes>
    <objectType>TestThree</objectType>
    <Attributes>
      <attribute name="value0">codeThree</attribute>
      <attribute name="value1">25</attribute>
      <attribute name="value2">3225</attribute>
      <attribute name="value3">225</attribute>
    </Attributes>
    <objectType>TestFour</objectType>
    <Attributes>
      <attribute name="value0">codeFour</attribute>
      <attribute name="value1">25</attribute>
      <attribute name="value2">35</attribute>
    </Attributes>
    <objectType>TestFive</objectType>
    <Attributes>
      <attribute name="value0">codeFive</attribute>
      <attribute name="value1">2</attribute>
      <attribute name="value2">3225</attribute>
      <attribute name="value3">225</attribute>
    </Attributes>
    <objectType>TestSix</objectType>
    <Attributes>
      <attribute name="value0">codSix</attribute>
      <attribute name="value1">2</attribute>
      <attribute name="value2">3225</attribute>
      <attribute name="value3">225</attribute>
    </Attributes>
  </object>
  <Types>
    <Type>
      <temp>TestOne</temp>
      <ID>2847</ID>
      <Is_Ingest>0</Is_Ingest>
      <Category>NAV</Category>
      <CategoryTwo>NAVAid</CategoryTwo>
      <Class>codeOne</Class>
      <New_Attribute>nisting</New_Attribute>
      <New_Value>52</New_Value>
      <Condition>value1=35</Condition>
    </Type>
    <Type>
      <temp>TestTwo</temp>
      <ID>2847</ID>
      <Is_Ingest>0</Is_Ingest>
      <Category>NAV</Category>
      <CategoryTwo>NAVAid</CategoryTwo>
      <Class>codeTwo</Class>
      <New_Attribute>nisting</New_Attribute>
      <New_Value>53</New_Value>
      <Condition>value1!=33</Condition>
    </Type>
    <Types>
      <Type>
        <temp>TestThree</temp>
        <ID>28247</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>NAVAid</CategoryTwo>
        <Class>codeThree</Class>
        <New_Attribute>nisting</New_Attribute>
        <New_Value>52</New_Value>
        <Condition>value1=35</Condition>
      </Type>
      <Type>
        <temp>TestFour</temp>
        <ID>2847</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>NAVAid</CategoryTwo>
        <Class>codeFour</Class>
        <New_Attribute>AidM</New_Attribute>
        <New_Value>45</New_Value>
        <Condition>value1!=33 & value1!=28</Condition>
      </Type>
      <Type>
        <temp>TestFive</temp>
        <ID>2847</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>Aid</CategoryTwo>
        <Class>codeFive</Class>
        <New_Attribute>AidM</New_Attribute>
        <New_Value>4</New_Value>
        <Condition>!value</Condition>
      </Type>
      <Type>
        <temp>TestSix</temp>
        <ID>2847</ID>
        <Is_Ingest>0</Is_Ingest>
        <Category>NAV</Category>
        <CategoryTwo>Aid</CategoryTwo>
        <Class>codeSix</Class>
        <New_Attribute>AidM</New_Attribute>
        <New_Value>4</New_Value>
      </Type>
    </Types>
  </outPut>

Here is the xsl

<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="*"/>
    <xsl:template match="/Input">
        <objects>
            <xsl:for-each select="Output">
                <object type="{object/objectType}">
                    <xsl:variable name="attributes" select="Attributes/*"/>
                    <xsl:variable name="matching-template" select="/Output/Types/Type[temp=$attributes and class=$attributes]"/>
                    <template>
                        <xsl:value-of select="$matching-template/New_Attribute"/>
                        <xsl:value-of select="$matching-template/New_Value"/>
                    </template>
                </object>
            </xsl:for-each>
        </objects>
    </xsl:template>
</xsl:stylesheet>

the expected output

<output>
    <object>
        <objectType>TestOne</objectType>
        <Attributes>
            <attribute name="value0">codeOne</attribute>
            <attribute name="value1">25</attribute>
            <attribute name="value2">35</attribute>
            <attribute name="nisting">52</attribute>
        </Attributes>
        <objectType>TestTwo</objectType>
        <Attributes>
            <attribute name="value0">codeTwo</attribute>
            <attribute name="value1">25</attribute>
            <attribute name="value2">35</attribute>
            <attribute name="NAV">NAVAID</attribute>
            <attribute name="value2">35</attribute>
        </Attributes>
    </object>
</output>

1 Answers1

0

Note: Just in case someone is wondering how this answer is related to the (edited) question above: Following was the accepted answer for the first version of this question on 9/23/2014. On 10/4/2014, the OP was changed nearly completely (instead of just posting a follow up question) and the answer was unaccepted by OP. For convenience, original question was:

I want to parse the following

<points>
    <point>
      <A>test=11 or test=12</A>
      <B>pointer> test!=7847</pointer>  
    </point>
</points> 

I want to get something like

<out>
<att>test</att>
<att2>=</att>
<att3>or</att3>
<att4>12</att4>
</out>  

I have used somthing like
<xsl:variable name="A" select="substring(/points/point/test,1)
it didn't help to get the "or" "and" ......

Accepted answer was:

Your XML is not valid, I guess it should be <B><pointer> test!=7847</pointer></B> instead of <B>pointer> test!=7847</pointer>.
Though not clear on which rules you want to get the desired ouput and if the element names are static or should be generated dynamic, following XSLT would work:

<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:template match="/*">
     <xsl:apply-templates select="//A"/>
  </xsl:template>

  <xsl:template match="A">
  <xsl:variable name="spaceToken" select="tokenize(., ' ')"/>
  <xsl:variable name="firstEqualToken" select="tokenize($spaceToken[1], '=')"/>
  <xsl:variable name="secondEqualToken" select="tokenize($spaceToken[3], '=')"/>
  <xsl:variable name="equalString" select="substring($spaceToken[1],5,1)"/>
   <out>
    <att>
     <xsl:value-of select="$firstEqualToken[1]"/>
    </att>
    <att2>
     <xsl:value-of select="$equalString"/>
    </att2>
    <att3>
     <xsl:value-of select="$spaceToken[2]"/>
    </att3>
    <att4>
     <xsl:value-of select="$secondEqualToken[2]"/>
   </att4>
  </out>
</xsl:template>
</xsl:stylesheet>

Output:

<?xml version="1.0" encoding="UTF-8"?>
<out>
 <att>test</att>
 <att2>=</att2>
 <att3>or</att3>
 <att4>12</att4>
</out>  

And to add something of maybe more value - your select-statement select="substring(/points/point/test,1) won't work like intended - substring() is a function working with strings, /points/point is the beginning of an xpath that won't get "test" in the A-text. "test" is part of the value of the text of the node named "A". You'll get the text e.g. with the xpath //points/point/A/text(). You can apply the substring()-function as follows substring(string, startpoint, length), so to get the "=" in "test=11" for $test='test=11' it's substring($test, 5, 1).

Reference: W3C - XPath - substring, and maybe of interest a good explanation provided in first answer here: XPath - Difference between node() and text()

Update: For question mentioned in comment below how to handle the != in <B> test!=7847</B> - it depends. As it's not clear 1) if the XML given in the OP is the only possible input to process or if there is a variety of different equations to be split and 2) how and why the output should look like the suggested output in the OP.
It's already mentioned that the output should "look like" the suggested ouput, but it'd be better to give the whole expected output as I just wonder why the 11 is missing for <A>test=11 or test=12</A>. I would have expected that the desired output should represent all possible conditions, like name (test), condition (=), value(s) to be checked for equality (11 and/or 12). Maybe only the max value is of interest?
Further questions are: 3) if only conditions based on equality are possible - = and != - or if it's possible that e.g. < and > are in the condition of the input and 4) if it's possible that there are more than 2 optional test-expressions and 5) if those conditions would always be optional (using or) or could also be including (using and).
And finally I have to admit that I'm not sure what you mean with "how to change the '=' as equals and '!=' as not equal to compare the values" - do you want to have for the example output <att2>equals</att2> instead of <att2>=</att2>?

Coming back to the first question in the comment - if you should write a second template matching <B> to handle the != - not knowing the possible input it's not easy to give any advice. I'd expect that it's possible that <point> has more than two entries (C, D, ..) and that it's possible that <A> contains an expression using != and <B> contains an expression using =. So I would suggest to use a more dynamic approach - using a template matching all children of <point>, check for each text in every child if a logical operator is contained (and / or), then handle every expression (test=12, test!=12) by first checking if != is contained - if so, tokenize over !=, if not, check if = is contained, if, then tokenize over =, and generate dynamic elements as the given <B> condition would only result in 3 elements - <att>test</att> <att2>!=</att> <att>7847</att> and also because of question 4) above.

If further input is needed, it would be helpful if you just update your question to provide some more information; not necessarily by answering all questions I mentioned, but at least considering them as than it'd be easier to help you to get your desired output.

Community
  • 1
  • 1
matthias_h
  • 11,356
  • 9
  • 22
  • 40
  • This is a great help. I got one more question should I create another template for test!=7847 ? Moreover, how do change the '=' as equals and '!=' as not equal to compare the values. Thanks – user3983344 Sep 24 '14 at 14:30
  • @user3983344 Glad I was already able to help you a bit. For the questions in your comment - I've just updated my answer – matthias_h Sep 24 '14 at 18:32