Check for XML header - xslt

How can i check in XSLT that an XML contains XML headers?
Example XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data>
<test>1</test>
</Data>
I want to check if the <?xml/> header exists.
<xsl:if test="xml header exists">
do something
</xsl:if>
// otherwise?
Thanks

The <?xml version="1.0" encoding="UTF-8" standalone="yes"?> is called the XML declaration and it is not part of the XSLT/XPath/XQuery data model so you can't access it or check for it using XSLT/XPath/XQuery.

Related

How to use XSLT when my XML contains a Prefix?

I have this XML below and I'm trying to print the content of the MyField element using XSLT. Unfortunately I can't make it work. Can you help me fix my XSLT?
XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="my_xsl.xsl"?>
<ns:Collection>
<Load>
<Item>
<MyField>Please Print Me</MyField>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:value-of select="ns:Collection/Load/Item/MyField" />
Your XML is not namespace well formed because the namespace prefix "ns" has not been bound to any namespace URI.
XSLT cannot process XML input unless it is namespace well formed.
Use namespace for ns: in the root element

How to add cxml doctype using XSLT

I am generating correct cxml but doctype is missing in the beginning.
How can I add the below doc type after <?xml version="1.0" encoding="utf-8"?> and copy the remaining xml using XSLT mapping.
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.032/cXML.dtd">
Desired output should be like
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.032/cXML.dtd">
<xml>
<field>.... (followed by remaining xml structure)
Thanks,
Varun
Try
<xsl:output method="xml"
doctype-system="http://xml.cxml.org/schemas/cXML/1.2.032/cXML.dtd"
/>

Format-number from ###.0 to ###.00

I working with a project in BizTalk where use xslt to convert from and edifact file to an UBL file.
The edifact file contains price values of ###.0 and that do not work. I want to change it to ###.00 using format-number. But I cannot make it work.
This is what I have made so far:
<cbc:Value>
<xsl:variable name="SumOfNodes" select="edi:PRI/edi:C509/C50902"/>
<xsl:value-of select="format-number($SumOfNodes, '0.00')"/>
</cbc:Value>
I am using this stylesheet:
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:edi="http://schemas.microsoft.com/BizTalk/EDI/EDIFACT/2006/MEDIAMARKT"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Order-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
exclude-result-prefixes="msxsl edi">
Any ideas on how to solve this??
This may be due to undeclared namespace in your XSLT. Please check whether namespaces are declared correctly in your XSLT. Unless you show the full XSLT coding with XML coding, we cannot able to provide solution. However please refer the below Sample XML and XSLT with the output
XSLT:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="chapter">
<Value>
<xsl:variable name="num" select="number"/>
<xsl:value-of select="format-number($num,'00.00')"/>
</Value>
</xsl:template>
</xsl:stylesheet>
Sample XML
<?xml version="1.0"?>
<chapter>
<number>45</number>
</chapter>
Output
<?xml version='1.0' ?>
<Value>45.00</Value>

XSLT - using hardcoded values and looping on them

I'm very new to xslt and trying to learn. The focus to transform my data xml and bind the output xml to the adobe form.
I have a xml of the following structure.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<envelope xmlns="http://www.mydata.de/xem/reporting/datafile">
<sources>
<source>
<data>
<REPORT>
<EM_ESOURCE>
<EM_ES_MEASURE>
<ID>1037343</ID>
<ES_ID>1006222</ES_ID>
<ES_NAME>MFC-D-002</ES_NAME>
<EM_MAT_NAME>Cyprinella leedsi</EM_MAT_NAME>
<START_DATE>1/19/98</START_DATE>
<LABORATORY>Thornton</LABORATORY>
<LC50>>100%</LC50>
<TESTTYPE/>
<IC25/>
</EM_ES_MEASURE>
<EM_ES_MEASURE>
<ID>1037344</ID>
<ES_ID>1006222</ES_ID>
<ES_NAME>MFC-D-002</ES_NAME>
<EM_MAT_NAME>C Dubia</EM_MAT_NAME>
<START_DATE>3/2/98</START_DATE>
<LABORATORY>Thornton</LABORATORY>
<LC50>>120%</LC50>
<TESTTYPE>Routine</TESTTYPE>
<IC25/>
</EM_ES_MEASURE>
</EM_ESOURCE>
</REPORT>
</data>
</source>
</sources>
This is the result of one of the queries. The Adobe report requires the materials to be shown always in a particular order regardless of what the query returns. So I decided to hardcode the order of materials in the xsl internally, loop on this list and then fetch corresponding "LC50" values from the data xml.
Following is the xsl that I started:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rep="http://www.technidata.de/xem/reporting/datafile"
xmlns:s="http:/materials.data"
xmlns:java="http://xml.apache.org/xslt/java">
<xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8"/>
<!-- Suppress copy of restrictions -->
<!--xsl:template match="text()|#*"/-->
<xsl:key name="material-lookup" match="s:material" use="s:name"/>
<xsl:template match="/">
<REPORT>
<HEADERS>
<STARTDATE><xsl:value-of select="substring(/rep:envelope/rep:sources/rep:restrictions/rep:START_DATE,1,10)"/></STARTDATE>
<ENDDATE><xsl:value-of select="substring(/rep:envelope/rep:sources/rep:restrictions/rep:START_DATE,16,24)"/></ENDDATE>
<FACILITY><xsl:value-of select="normalize-space(/rep:envelope/rep:sources/rep:restrictions/rep:ID_ATTRIBUTE_ID_NAME)"/></FACILITY>
</HEADERS>
<MATERIALS>
</MATERIALS>
</REPORT></xsl:template>
<s:materials>
<s:material>
<s:name>Cyprinella leedsi</s:name>
<s:parameter>LC(ROUTINE) </s:parameter>
</s:material>
<s:material>
<s:name>C Dubia</s:name>
<s:parameter>LC50(ROUTINE) </s:parameter>
</s:material>
</s:materials>
</xsl:stylesheet>
I'm not sure how to fill in the the MATERIALS node with the materials in the order defined in the xslt and their corresponding LC50 values from the data xml.
Use the document('') function to XPath into the XSLT file itself.

xml namespaces in xsl transform - ignore blank?

I'm new to xsl and am trying to write a template to transform xml to html.
I have an xml document that begins
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns:autn="http://schemas.com/aci/"
xmlns="http://iptc.org/std/nar/2006-10-01/">
<name>Bob</name>
and my xsl template begins
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:autn="http://schemas.autonomy.com/aci/">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:template match="/">
...
<body>
<p>user name:</p>
<p><xsl:value-of select="data/name"/></p>
The problem is, if I do
I don't get anything back for the value-of select.
If I do
I get 'Bob' but I lose all my html.
What am I missing?
You are missing the default namespace of the XML document:
xmlns="http://iptc.org/std/nar/2006-10-01/"
Add it to the XSLT as well:
<xsl:stylesheet version="1.0"
xmlns:mynamespace="http://iptc.org/std/nar/2006-10-01/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:autn="http://schemas.autonomy.com/aci/">
And use that namespace in the xsl:value-of:
<xsl:value-of select="mynamespace:data/mynamespace:name" />