Already searched for an answer here, but couldn't find any suitable solution...!
I'm trying to write a XSLT tranformation, starting from a SOAP response message, to be transformed to a XML message (the XML tags will not be the same).
Here is my input SOAP message :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CatalogPriceResponseParams xmlns="http://theurl.com">
<ArrayOfOutputCatalogItems>
<ItemID>003332</ItemID>
<ShipFromPartyWarehouseLocationID>901</ShipFromPartyWarehouseLocationID>
<Quantity>20.0</Quantity>
<UnitCode>PCE</UnitCode>
<UnitPriceAmount>104.9</UnitPriceAmount>
<UnitPricePerQuantity>1.0</UnitPricePerQuantity>
<UnitPricePerQuantityUOM>EA</UnitPricePerQuantityUOM>
<PricingAmountUnitPretaxAmount>104.9</PricingAmountUnitPretaxAmount>
</ArrayOfOutputCatalogItems>
<ArrayOfOutputCatalogItems>
<ItemID>003333</ItemID>
<ShipFromPartyWarehouseLocationID>901</ShipFromPartyWarehouseLocationID>
<Quantity>1.0</Quantity>
<UnitCode>PCE</UnitCode>
<UnitPriceAmount>100.9</UnitPriceAmount>
<UnitPricePerQuantity>1.0</UnitPricePerQuantity>
<UnitPricePerQuantityUOM>EA</UnitPricePerQuantityUOM>
<PricingAmountUnitPretaxAmount>100.9</PricingAmountUnitPretaxAmount>
</ArrayOfOutputCatalogItems>
</CatalogPriceResponseParams>
</soap:Body>
</soap:Envelope>
the desired output is :
<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xsi:noNamespaceSchemaLocation="genericResponse.xsd">
<getPrices>
<errorCode>0</errorCode>
<currency>EUR</currency>
<articleList>
<article>
<articleId>003332</articleId>
<icon>2</icon>
<priceList>
<price>
<price>104.9</price>
</price>
</priceList>
</article>
<article>
<articleId>003333</articleId>
<icon>2</icon>
<priceList>
<price>
<price>100.9</price>
</price>
</priceList>
</article>
</articleList>
</getPrices>
</TradeResponse>
I already started to write a XSLT transformation but this doesn"t give the expected result:
<xsl:stylesheet version="1.0" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="soap:*">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="/">
<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="genericResponse.xsd">
<getPrices>
<errorCode>
<xsl:value-of select="'0'"/>
</errorCode>
<currency>
<xsl:value-of select="'EUR'"/>
</currency>
<articleList>
<xsl:for-each select=".*/CatalogPriceResponseParams/ArrayOfOutputCatalogItems">
<article>
<articleId>
<xsl:value-of select="./ItemID"/>
</articleId>
<icon>
<xsl:value-of select="'2'"/>
</icon>
<priceList>
<price>
<price>
<xsl:value-of select="./UnitPriceAmount"/>
</price>
</price>
</priceList>
</article>
</xsl:for-each>
</articleList>
</getPrices>
</TradeResponse>
</xsl:template>
</xsl:stylesheet>
I hacve issue with the for-each instructions and I'm not able to address the XPathes I need.
Any help would be appreciated !
Many Thanks,
David.
As I mentioned in the comments, the main issue here is the default namespace declared in your XSLT. Once you fix that, and remove the unnecessary verbosity, you should be able to do with:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http://theurl.com"
exclude-result-prefixes="soap ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/soap:Envelope">
<TradeResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="genericResponse.xsd">
<getPrices>
<errorCode>0</errorCode>
<currency>EUR</currency>
<articleList>
<xsl:for-each select="soap:Body/ns0:CatalogPriceResponseParams/ns0:ArrayOfOutputCatalogItems">
<article>
<articleId>
<xsl:value-of select="ns0:ItemID"/>
</articleId>
<icon>2</icon>
<priceList>
<price>
<price>
<xsl:value-of select="ns0:UnitPriceAmount"/>
</price>
</price>
</priceList>
</article>
</xsl:for-each>
</articleList>
</getPrices>
</TradeResponse>
</xsl:template>
</xsl:stylesheet>
Related
Hi I have issue in the default namespace declaration. output xml elements are appended with the default namespace.
The input XML look like
<m:Request xmlns:m="http://www.NeededNamespace/1.4.0">
<Details>
<Records>50</Records>
<Start>1</Start>
<sortName>sortName</sortName>
</Details>
<search>
<criteria>
<comparative>
<Comparative>exactMatch</Comparative>
</comparative>
<name>STATECODE</name>
<value>CO</value>
</criteria>
<criteria>
<comparative>
<Comparative>exactMatch</Comparative>
</comparative>
<name>Version</name>
<value>4.0</value>
</criteria>
<criteria>
<comparative>
<Comparative>contains</Comparative>
</comparative>
<name>LEGALNAME</name>
<value>Citizens State Bank</value>
</criteria>
</search>
</m:Request>
The XSLT look like
<xsl:stylesheet version="1.0" exclude-result-prefixes="t" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://www.NotRequirednamespace.com">
<xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!--Stylesheet to remove all namespaces from a document-->
<!--NOTE: this will lead to attribute name clash, if an element contains
two attributes with same local name but different namespace prefix-->
<!--Nodes that cannot have a namespace are copied as such-->
<xsl:template match="/">
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<xys:To xmlns:xys="http://services.xys.com/framework/xysHeader/v2">
<xys:version>9.0</xys:version>
<xys:serviceName>DetailsManagement</xys:serviceName>
<xys:QOS>DEFAULT</xys:QOS>
<xys:operation>GetDetails</xys:operation>
</xys:To>
<ConsumerInfo xmlns="http://services.xys.com/framework/xysHeader/v2">
<xysApplicationName>SAP</xysApplicationName>
<xysCheckPermission>-1</xysCheckPermission>
<xysConsumerPlatform>CS</xysConsumerPlatform>
<xysLanguage>en</xysLanguage>
<xysLocale>US</xysLocale>
<xysLogLevel>false</xysLogLevel>
</ConsumerInfo>
<HeaderMetadata xmlns="http://services.xys.com/framework/xysHeader/v2">
<metadataContractVersion>2.0</metadataContractVersion>
<Id>414</Id>
<Timestamp>2014-11-20T14:17:30.908-0500</Timestamp>
</HeaderMetadata>
<xys:favouriteSausage xmlns:xys="http://services.xys.com/framework/xysHeader/v2">cumberland</xys:favouriteSausage>
</soap:Header>
<soap:Body>
<GetDetails xmlns="http://www.NeededNamespace/1.4.0">
<Message id="" version="" bodyType="FS-XML" timeStampCreated="2015-10-11T10:15:25.9144403-04:00" sourceLogicalId="" xmlns="http://www.ibm.com/industries/xys">
<ACGroup bodyCategory="" TPMode="RespondError"/>
<COMMAND>
<xsl:apply-templates/>
</COMMAND>
</Message>
</GetDetails>
</soap:Body>
</soap:Envelope>
</xsl:template>
<!--template to copy elements-->
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="http://www.NeededNamespace/1.4.0">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
<!--template to copy attributes-->
<xsl:template match="#*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!--template to copy the rest of the nodes-->
<xsl:template match="comment() | text() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
The output XML what i am getting is
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<xys:To xmlns:xys="http://services.xys.com/framework/xysHeader/v2">
<xys:version>9.0</xys:version>
<xys:serviceName>DetailsManagement</xys:serviceName>
<xys:QOS>DEFAULT</xys:QOS>
<xys:operation>GetDetails</xys:operation>
</xys:To>
<ConsumerInfo xmlns="http://services.xys.com/framework/xysHeader/v2">
<xysApplicationName>SAP</xysApplicationName>
<xysCheckPermission>-1</xysCheckPermission>
<xysConsumerPlatform>CS</xysConsumerPlatform>
<xysLanguage>en</xysLanguage>
<xysLocale>US</xysLocale>
<xysLogLevel>false</xysLogLevel>
</ConsumerInfo>
<HeaderMetadata xmlns="http://services.xys.com/framework/xysHeader/v2">
<metadataContractVersion>2.0</metadataContractVersion>
<Id>414</Id>
<Timestamp>2014-11-20T14:17:30.908-0500</Timestamp>
</HeaderMetadata>
<xys:favouriteSausage xmlns:xys="http://services.xys.com/framework/xysHeader/v2">cumberland</xys:favouriteSausage>
</soap:Header>
<soap:Body>
<GetDetails xmlns="http://www.NeededNamespace/1.4.0">
<Message xmlns="http://www.ibm.com/industries/xys" id="" version="" bodyType="FS-XML" timeStampCreated="2015-10-11T10:15:25.9144403-04:00" sourceLogicalId="">
<ACGroup bodyCategory="" TPMode="RespondError"/>
<COMMAND>
<Request xmlns="http://www.NeededNamespace/1.4.0">
<Details>
<Records>50</Records>
<Start>1</Start>
<sortName>sortName</sortName>
</Details>
<search>
<criteria>
<comparative>
<Comparative>exactMatch</Comparative>
</comparative>
<name>STATECODE</name>
<value>CO</value>
</criteria>
<criteria>
<comparative>
<Comparative>exactMatch</Comparative>
</comparative>
<name>Version</name>
<value>4.0</value>
</criteria>
<criteria>
<comparative>
<Comparative>contains</Comparative>
</comparative>
<name>LEGALNAME</name>
<value>Citizens State Bank</value>
</criteria>
</search>
</Request>
</COMMAND>
</Message>
</GetDetails>
</soap:Body>
</soap:Envelope>
But in the result I am getting the element as
<Request xmlns="http://www.NeededNamespace/1.4.0">
But i want the result tag as like below
<Request>
I dont want to redeclare the namespace which is already declared in the root tag of the same. I have tried all the option i have known and tried for last few days. can you please help me on this.
The input element has expanded name (local-part="Request", namespace="http://www.NeededNamespace/1.4.0"). If you don't want the output Request element to have a namespace declaration, then presumably you want it to be in the same namespace as its parent, that is you want its expanded name to be (local-part="Request", namespace="http://www.ibm.com/industries/xys"). An xsl:copy or xsl:copy-of instruction will never (even in 2.0) change the expanded name of the element being copied. So you can't achieve your desired output using xsl:copy or xsl:copy-of. You will need to create a new element with the same local name but a different namespace from the original, using <xsl:element name="{local-name()}" namespace="http://www.ibm.com/industries/xys"/>.
I have a xml document which looks like
<!-- language: lang-xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Request xmlns="fst" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<AccountServer e-dtype="int">3</AccountServer>
</Header>
<Response>
<ResponseList e-dtype="list">
<Response>
<RequestId e-dtype="string">ServiceOrderGetRef</RequestId>
<RequestObjName e-dtype="string">ServiceOrder</RequestObjName>
<ServiceOrder>
<CreateDt e-dtype="dateTime">2014-03-01 00:00:00</CreateDt>
<CreateWho e-dtype="string">vc</CreateWho>
<WorkflowStartDt e-dtype="dateTime">2014-04-01 00:00:00</WorkflowStartDt>
</ServiceOrder>
</Response>
<Response>
<ComponentList e-dtype="list"/>
<Count e-dtype="int">0</Count>
<RequestId e-dtype="string">ComponentFindRef</RequestId>
<RequestObjName e-dtype="string">Component</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
<Response>
<Count e-dtype="int">0</Count>
<CustomerContractList e-dtype="list"/>
<RequestId e-dtype="string">CustomerContractRef</RequestId>
<RequestObjName e-dtype="string">CustomerContract</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
<Response>
<Count e-dtype="int">0</Count>
<ProductList e-dtype="list"/>
<RequestId e-dtype="string">ProductRef</RequestId>
<RequestObjName e-dtype="string">Product</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
<Response>
<Count e-dtype="int">0</Count>
<NrcList e-dtype="list"/>
<RequestId e-dtype="string">NrcFindRef</RequestId>
<RequestObjName e-dtype="string">Nrc</RequestObjName>
<TotalCount e-dtype="int">0</TotalCount>
</Response>
</ResponseList>
</Response>
</Request>
I am using copy-of function to copy node ServiceOrder within another xml document
I want to modify text of node WorkFlowStartDt and CreateDt and then do a copy-of. How can I do this?
My copied serviceorder node should look like this after modifing text. Below is the result xml
<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess>
<Fetch e-dtype="boolean">true</Fetch>
<Order>
<AccountInternalId e-dtype="int">12345</AccountInternalId>
<Key>
<OrderId e-dtype="numeric">12345678</OrderId>
</Key>
</Order>
<ServiceOrderList e-dtype="list">
<ServiceOrder xmlns="fst" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance">
<CreateDt e-dtype="dateTime">2014-03-02 00:00:00</CreateDt>
<CreateWho e-dtype="string">vc</CreateWho>
<WorkflowStartDt e-dtype="dateTime">2014-05-01 00:00:00</WorkflowStartDt>
</ServiceOrder>
</ServiceOrderList>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</RequestList>
</CustomerUdtRequest>
</Request>
Below is my xslt processor file
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess> <Order> <AccountInternalId e-dtype="int">
<xsl:value-of
select="/Request/Response/ResponseList/Response/ServiceOrder/AccountInternalId"/>
</AccountInternalId> <Key> <OrderId e-dtype="numeric"> <xsl:value-of select="/Request/Response/ResponseList/Response/ServiceOrder/OrderId"/>
</OrderId>
</Key>
</Order>
<ServiceOrderList e-dtype="list">
<xsl:copy-of select="/Request/Response/ResponseList/Response/ServiceOrder"/>
</ServiceOrderList>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</xsl:if>
</RequestList>
</CustomerUdtRequest>
</Request>
</xsl:template>
</xsl:stylesheet>
I want to modify text of node WorkFlowStartDt and CreateDt and then do
a copy-of.
That would be an unnecessary complication. You can modify nodes while you add them to the output tree.
Since you essentially want to copy everything "as is" except two nodes, it would be best to start with an identity transform template, then add an "exception" template for the two specific nodes that need modifying (one template for both, since the modification is identical).:
<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"/>
<!-- identity transformation -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CreateDt | WorkFlowStartDt">
<xsl:copy>
<xsl:value-of select="concat('**', ., '**')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Added:
In response to the edited question, try this stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="fst"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess>
<Order>
<AccountInternalId e-dtype="int">
<!-- THIS DOESN'T POINT TO ANY EXISTING NODE!! -->
<xsl:value-of select="ns:Request/ns:Response/ns:ResponseList/ns:Response/ns:ServiceOrder/ns:AccountInternalId"/>
</AccountInternalId>
<Key>
<OrderId e-dtype="numeric">
<!-- THIS DOESN'T POINT TO ANY EXISTING NODE!! -->
<xsl:value-of select="ns:Request/ns:Response/ns:ResponseList/ns:Response/ns:ServiceOrder/ns:OrderId"/>
</OrderId>
</Key>
</Order>
<xsl:apply-templates select="ns:Request/ns:Response/ns:ResponseList/ns:Response/ns:ServiceOrder"/>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</RequestList>
</CustomerUdtRequest>
</Request>
</xsl:template>
<xsl:template match="ns:ServiceOrder">
<xsl:copy>
<xsl:copy-of select="ns:CreateWho"/>
<xsl:apply-templates select="ns:CreateDt | ns:WorkflowStartDt"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ns:CreateDt | ns:WorkflowStartDt">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:value-of select="concat('**', ., '**')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied to your input (minus the illegal opening comment), the following result is obtained:
<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Header>
<OperatorName e-dtype="string">ws</OperatorName>
<ApplicationName e-dtype="string">ws</ApplicationName>
</Header>
<CustomerUdtRequest>
<RequestList e-dtype="list">
<LogicalServiceOrder>
<RequestId e-dtype="string">MyExistingOrder</RequestId>
<LogicalServiceOrderPreProcess>
<Order>
<AccountInternalId e-dtype="int"/>
<Key>
<OrderId e-dtype="numeric"/>
</Key>
</Order>
<ServiceOrder xmlns="fst" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CreateWho e-dtype="string">vc</CreateWho>
<CreateDt e-dtype="dateTime">**2014-03-01 00:00:00**</CreateDt>
<WorkflowStartDt e-dtype="dateTime">**2014-04-01 00:00:00**</WorkflowStartDt>
</ServiceOrder>
</LogicalServiceOrderPreProcess>
</LogicalServiceOrder>
</RequestList>
</CustomerUdtRequest>
</Request>
I am trying to apply a transformation to generate an rdf document. My source xml contains an element that I want to ignore, but the output (generated via SAP's transformation test tool) includes the (concatenated!) texts of the elements from SYSINFO.
I have tried several variations (such as xsl:apply-templates select="asx:abap/asx:/values/CT" )
but then I get no output at all. Hmm. Have spent several hours trying different things and researching, but have gotten nowhere. Any help really appreciated. John
Here is my sample xml (fragment)
<?xml version="1.0" encoding="utf-8"?>
<asx:abap xmlns:asx="http://www.sap.com/abapxml"version="1.0">
<asx:values>
<SYSINFO>
<SERVER_NAME>sapserver06</SERVER_NAME>
<SYSTEM_ID>ECC</SYSTEM_ID>
<SAP_RELEASE>701</SAP_RELEASE>
<SYS_NR>00</SYS_NR>
<CLIENT>800</CLIENT>
<EXE_USER>XXX</EXE_USER>
<LOGON_LANGUAGE>E</LOGON_LANGUAGE>
<DATE>2013-04-09</DATE>
<TIME>12:06:58</TIME>
<TIMEZONE>CST</TIMEZONE>
<OPERATING_SYSTEM>Windows NT</OPERATING_SYSTEM>
<LICENSE_NUMBER>YYY</LICENSE_NUMBER>
<SAP_CUSTOMER>ZZZ</SAP_CUSTOMER>
<CLIENT_CATEGORY>C</CLIENT_CATEGORY>
<LANGUAGES_INSTALLED>JED</LANGUAGES_INSTALLED>
</SYSINFO>
<CT>
<item>
<ID>1</ID>
<TABNAME>T000</TABNAME>
<FIELDNAME>ADRNR</FIELDNAME>
<KEYFLAG/>
<ROLLNAME>CHAR10</ROLLNAME>
</item>
.....
</CT>
</asx:values>
</asx:abap>
Here is the transformation
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sap_coda="http://www.sapmantics.com/sap_coda#" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<rdf:RDF>
<xsl:apply-templates/>
</rdf:RDF>
</xsl:template>
<xsl:template>
<xsl:for-each select="//item">
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="TABNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="FIELDNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
<xsl:if test="KEYFLAG=X">
<sap_coda:keyflag>X</sap_coda:keyflag>
</xsl:if>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</xsl:for-each>
</xsl:template>
</xsl:transform>
And finally, here is the output:
<?xml version="1.0" encoding="utf-16"?>
sapserver06ECC70100800XXXE2013-04-0917:21:50CSTWindowsNTYYYZZZCJED
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sap_coda="http://www.sapmantics.com/sap_coda#">
<rdf:Description rdf:about="T000">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>....
The concatenation of your <SYSINFO/> text nodes can be explained by the default handing for element nodes:
http://www.w3.org/TR/xslt#built-in-rule
I don't know which XSLT processor you are using, but I am surprised that your //item handler wasn't flagged for lacking a #match attribute. You can update it with the following, and it will handle each <item/> element in document order:
<xsl:template match="item">
<rdf:Description>
To keep your SYSINFO content from being included in your RDF (if that is your intent), update your root template with the following:
<rdf:RDF>
<xsl:apply-templates select="//item"/>
</rdf:RDF>
-----------EDIT--------------------------
With this input
<?xml version="1.0" encoding="utf-8"?>
<asx:abap xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<SYSINFO>
<SERVER_NAME>sapserver06</SERVER_NAME>
<SYSTEM_ID>ECC</SYSTEM_ID>
<SAP_RELEASE>701</SAP_RELEASE>
<SYS_NR>00</SYS_NR>
<CLIENT>800</CLIENT>
<EXE_USER>XXX</EXE_USER>
<LOGON_LANGUAGE>E</LOGON_LANGUAGE>
<DATE>2013-04-09</DATE>
<TIME>12:06:58</TIME>
<TIMEZONE>CST</TIMEZONE>
<OPERATING_SYSTEM>Windows NT</OPERATING_SYSTEM>
<LICENSE_NUMBER>YYY</LICENSE_NUMBER>
<SAP_CUSTOMER>ZZZ</SAP_CUSTOMER>
<CLIENT_CATEGORY>C</CLIENT_CATEGORY>
<LANGUAGES_INSTALLED>JED</LANGUAGES_INSTALLED>
</SYSINFO>
<CT>
<item>
<ID>1</ID>
<TABNAME>T000</TABNAME>
<FIELDNAME>ADRNR</FIELDNAME>
<KEYFLAG/>
<ROLLNAME>CHAR10</ROLLNAME>
</item>
</CT>
</asx:values>
</asx:abap>
and this stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sap_coda="http://www.sapmantics.com/sap_coda#"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<rdf:RDF>
<xsl:apply-templates select="//item"/>
</rdf:RDF>
</xsl:template>
<xsl:template match="item[parent::CT]">
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="TABNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="FIELDNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
<xsl:if test="KEYFLAG=X">
<sap_coda:keyflag>X</sap_coda:keyflag>
</xsl:if>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</xsl:template>
<xsl:template match="item[parent::FOO]"/>
<xsl:template match="item"/>
</xsl:transform>
I get this output from Saxon-EE 9.4.0.3:
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:sap="http://www.sap.com/sapxsl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sap_coda="http://www.sapmantics.com/sap_coda#">
<rdf:Description rdf:about="T000">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description rdf:about="ADRNR">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</rdf:RDF>
and this output from xstlproc:
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sap="http://www.sap.com/sapxsl" xmlns:sap_coda="http://www.sapmantics.com/sap_coda#">
<rdf:Description rdf:about="T000">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description rdf:about="ADRNR">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</rdf:RDF>
I'm stuck to getting data from this xml:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<AAA>Header</AAA>
<BBB>
<CCC>
<DDD>
<EEE>123123</EEE>
<FFF>
<GGG>
<HHH>Body</HHH>
<III>1</III>
</GGG>
<GGG>
<HHH>Body</HHH>
<III>3</III>
</GGG>
</FFF>
</DDD>
</CCC>
<CCC>
<DDD>
<EEE>234234</EEE>
<FFF>
<GGG>
<HHH>Body</HHH>
<III>2</III>
</GGG>
<GGG>
<HHH>Body</HHH>
<III>4</III>
</GGG>
<GGG>
<HHH>Body</HHH>
<III>6</III>
</GGG>
</FFF>
</DDD>
</CCC>
<CCC>
<DDD>
<EEE>345345</EEE>
<FFF>
<GGG>
<HHH>Body</HHH>
<III>7</III>
</GGG>
</FFF>
</DDD>
</CCC>
</BBB>
</document>
Needed result should be:
Header;
Body;1;123123
Body;3;123123
Body;2;234234
Body;4;234234
Body;6;234234
Body;7;345345
My xslt looks:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="text" encoding="Windows-1257" indent="yes"/>
<xsl:template match="/">
<!--Start Header--><xsl:value-of select="document/AAA"/><xsl:text>;</xsl:text>
<!--End Header--><xsl:text>
</xsl:text>
<xsl:for-each select="document/BBB/CCC/DDD/FFF/GGG">
<!--Start Body--><xsl:value-of select="HHH"/><xsl:text>;</xsl:text>
<xsl:value-of select="III"/><xsl:text>;</xsl:text>
<xsl:value-of select="../EEE"/><--This doesn't work-->
<!--End Body--><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
now I have problem to get value from EEE tag. Please help to solve it because I have no idea how to do it.
From your for-each statement the current context that you are working at is document/BBB/CCC/DDD/FFF/GGG.
The full path of the EEE statement is document/BBB/CCC/DDD/EEE.
Therefore you need to come back two levels to reach the EEE node from the GGG node:
<xsl:value-of select="../../EEE"/>
I have the following XML
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="sample.xsl" type="text/xsl"?>
<rss version="2.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel
xmlns:cfi="http://www.microsoft.com/schemas/rss/core/2005/internal">
<title cf:type="text">The Hindu - Front Page</title>
<link>http://www.hindu.com/</link>
<description cf:type="text">The Internet edition of The Hindu,
India's national newspaper</description>
<image>
<url>http://www.hindu.com/hindu/hindux.gif</url>
<title>hindu.com</title>
<link>http://www.hindu.com/</link>
</image>
<item>
<title cf:type="text"
xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005"
>ISRO spectrum deal under review: Centre</title>
</item>
<item>
<title cf:type="text"
xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005"
>Response from Devas</title>
</item>
</channel>
</rss>
The rss/channel/item can be of any count(in the current case it's count is 2). I need to display the Titles as a Marquee one after the other as follows
ISRO spectrum deal under review: Centre, Response from Devas,....,....
How can I accomplish this in XSLT? kindly advice
Thanks
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cfi="http://www.microsoft.com/schemas/rss/core/2005/internal"
xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005"
xmlns:dc="http://purl.org/dc/elements/1.1/"
exclude-result-prefixes="cfi cf dc">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/*">
<div id="marquee">
<xsl:apply-templates select="channel/item/title"/>
</div>
</xsl:template>
<xsl:template match="title">
<xsl:value-of select="."/>
<xsl:if test="not(position() = last())">, </xsl:if>
</xsl:template>
</xsl:stylesheet>
Result against your sample:
<div id="marquee">ISRO spectrum deal under review: Centre, Response from Devas</div>
In addition to #Flack correct answer, in XSLT 2.0 xsl:value-of instruction preserves sequence. So, this stylesheet:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<div id="marquee">
<xsl:value-of select="rss/channel/item/title"
separator=", "/>
</div>
</xsl:template>
</xsl:stylesheet>
Also outputs:
<div id="marquee"
>ISRO spectrum deal under review: Centre, Response from Devas</div>