I really worked many ways to solve it but I couldn't able to finish it.
Code snippet Click here for code and result
My request payload is
<process>
<TransactionType>
<data_xml>
<transaction>
<parent>{"26":"27"}</parent>
<sub_documents>
<transactionLine>
<parent_doc_number>2</parent_doc_number>
<bidvalue>LOV</bidvalue>
</transactionLine>
<transactionLine>
<parent_doc_number>26</parent_doc_number>
<bidvalue>EATY</bidvalue>
</transactionLine>
<transactionLine>
<parent_doc_number>26</parent_doc_number>
<bidvalue>CLD</bidvalue>
</transactionLine>
<transactionLine>
<_parent_doc_number>31</_parent_doc_number>
<bidvalue>YOND</bidvalue>
</transactionLine>
<transactionLine>
<_parent_doc_number>6</_parent_doc_number>
<bidvalue>CHEG</bidvalue>
</transactionLine>
</sub_documents>
</transaction>
</data_xml>
</TransactionType>
and the excepted output would be
<Ref>EATY</Ref>
<LineSeq>1</LineSeq>
<Ref>CLD</Ref>
<LineSeq>2</LineSeq>
My xslt codeis
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<xsl:for-each select="/process/TransactionType/data_xml/transaction/sub_documents/transactionLine">
<xsl:variable name="PDocNum" select="parent_doc_number"/>
<xsl:if test="contains(/process/TransactionType/data_xml/transaction/parent,PDocNum)">
<Ref>
<xsl:value-of select="bidvalue"/>
</Ref>
<LineSeq>
<xsl:value-of select="position()"/>
</LineSeq>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:transform>
The logic what i am trying is from the parent{"26":"27"} attribute value i will check whether the parent_doc_number is there like using contains function. Here the fist problem is the request <parent_doc_number> not contains quotes("") so with out I pass that will give even the <parent_doc_number>2</parent_doc_number>. But this is not the excepted.
The sequence also not generating properly. I spent lot of time and not finished. Please help me out on this tricky thing.
CodePudding user response:
The logic you describe is not entirely clear. Assuming that the parent
element lists the parent_doc_number
values of all the transactionLine
elements you want to output, enclosed in quotes and separated by a colon, you could use:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="tx" match="transactionLine" use="parent_doc_number" />
<xsl:template match="/process">
<output>
<xsl:for-each select="key('tx', tokenize(translate(//parent, '{}"', ''), ':'))">
<Ref>
<xsl:value-of select="bidvalue"/>
</Ref>
<LineSeq>
<xsl:value-of select="position()"/>
</LineSeq>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
to get:
Result
<?xml version="1.0" encoding="UTF-8"?>
<output>
<Ref>EATY</Ref>
<LineSeq>1</LineSeq>
<Ref>CLD</Ref>
<LineSeq>2</LineSeq>
</output>
Note that contains()
is not a good test to use here, because 26
also contains 2
and 6
. You could use something along the lines of:
<xsl:for-each select="//transactionLine[contains(//parent, concat('"', parent_doc_number, '"'))]">
but using a key in the opposite direction is both more elegant and more efficient.