I've got this bit of XML:
<?xml version="1.0" encoding="UTF-8"?>
<photo-caption>
<p>
<?EM-dummyText caption?>
<ld pattern=" "/>
<s2>Photo </s2>
<source>
<?EM-dummyText photographer?>
</source>
</p>
</photo-caption>
I want this output:
<?xml version="1.0" encoding="UTF-8"?>
<photo-caption>
<p>
<s2><?EM-dummyText heading?></s2>
<?EM-dummyText caption?>
</p>
</photo-caption>
This is the XSLT I'm using at the moment:
<xsl:stylesheet version="1.0"
exclude-result-prefixes="subst"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:subst="http://tempuri.org">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<subst:photo-caption>
<p>
<s2>
<?EM-dummyText heading?>
</s2>
<?EM-dummyText caption?>
</p>
</subst:photo-caption>
<xsl:variable name="subst" select="document('')/*/subst:photo-caption"/>
<xsl:template match="photo-caption">
<xsl:copy-of select="$subst"/>
</xsl:template>
</xsl:stylesheet>
... which yields this the output:
<?xml version="1.0" encoding="utf-8"?>
<subst:photo-caption xmlns:subst="http://tempuri.org" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<p>
<s2><?EM-dummyText heading?></s2><?EM-dummyText caption?>
</p>
</subst:photo-caption>
How do I remove the prefixes and namespace attributes from the output? Or is there a better way to do this?
If you simply want to output that fragment then use
<xsl:template match="photo-caption">
<photo-caption>
<p>
<s2>
<xsl:processing-instruction name="EM-dummyText">heading</xsl:processing-instruction>
</s2>
<xsl:processing-instruction name="EM-dummyText">caption</xsl:processing-instruction>
</p>
</photo-caption>
</xsl:template>
Related
I have trouble in transform part of a xml to a new xml without namespace.
Input xml is:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<node1 xmlns="http://a.com">
<ServiceData>
<b:test xmlns:b="http://b.com">
<b:somtag>
</b:somtag>
</b:test>
</ServiceData>
</node1>
and what I want is:
<a>
<c>
<ServiceData>
<b:test xmlns:b="http://b.com">
<b:somtag>
</b:somtag>
</b:test>
</ServiceData>
</c>
</a>
The format I want is with no namespace for ServiceData.
Any help is appreciated, thanks.
Added, I tried to use this xsl, but I can't remove "xmlns="http://a.com""
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:test="http://a.com" exclude-result-prefixes="test">
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:template match="/">
<a><c><ServiceData><xsl:copy-of select="//test:ServiceData/*"/></ServiceData></c></a>
</xsl:template>
</xsl:stylesheet>
The result I got is:
<a>
<c>
<ServiceData>
<b:test xmlns:b="http://b.com" xmlns="http://a.com">
<b:somtag>
</b:somtag>
</b:test>
</ServiceData>
</c>
</a>
How about:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://a.com">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/node1">
<a>
<c>
<ServiceData>
<xsl:copy-of select="ServiceData/*" copy-namespaces="no" />
</ServiceData>
</c>
</a>
</xsl:template>
</xsl:stylesheet>
Added:
I assumed you could use an XSLT 2.0 processor, because your stylesheet says version="2.0". If that's not true, then you cannot use xsl:copy-of; instead, you must reconstruct the elements with their original names and namespaces:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:test="http://a.com"
exclude-result-prefixes="test">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/test:node1">
<a>
<c>
<ServiceData>
<xsl:apply-templates select="test:ServiceData/*"/>
</ServiceData>
</c>
</a>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Note:
A redundant namespace declaration should not make any difference to the receiving application. The results received here are semantically identical to the result you show in your question.
I used XSLT for converting document from XML to text. But extra line space is produced after every instance, please suggest how to solve this problem. Here I attached screen shot for your reference.
Example
Input:
<?xml version="1.0" encoding="UTF-8"?>
<book-part book-part-type="chapter" id="chapter1">
<book-part-meta>
<title-group>
<label>1</label>
<title>The Developmental Origins of Health and Disease—Where Did It All Begin?</title>
</title-group>
<contrib-group>
<contrib contrib-type="author"><name><surname>Nicholas</surname><given-names>L. M.</given-names></name></contrib>
<contrib contrib-type="author"><name><surname>Ozanne</surname><given-names>S. E.</given-names></name></contrib>
</contrib-group>
</book-part-meta>
<body>
<sec id="sec1_1">
<label>1.1</label>
<title>THE DEVELOPMENTAL ORIGINS OF ADULT DISEASE—ORIGINS OF THE HYPOTHESIS</title>
<p>One of the earliest proposals establishing the association between early life events and the risk for disease in adult life was more than 80 years ago by Kermack and colleagues.
<fig id="fig1_1">
<label>FIGURE 1.1</label>
<caption><p>Exposure to suboptimal nutrition during fetal development results in an adaptive response to optimize the growth of key body organs to the detriment of others. </p></caption>
<graphic href="001x001"/>
</fig>
</p>
</sec>
</body>
</book-part>
XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:output method="text" omit-xml-declaration="yes" standalone="yes" indent="no"/>
[enter image description here][1]
<xsl:template match="fig/label"/>
<xsl:template match="fig/caption">
<xsl:text disable-output-escaping="yes">\caption{</xsl:text><xsl:apply-templates/><xsl:text disable-output-escaping="yes">}</xsl:text>
</xsl:template>
<xsl:template match="fig/graphic">
<xsl:text disable-output-escaping="yes">\includegraphics{</xsl:text><xsl:apply-templates select="#href"/><xsl:text disable-output-escaping="yes">.pdf}</xsl:text>
</xsl:template>
</xsl:stylesheet>
You can use <xsl:strip-space elements="*" /> to remove extra line breaks.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:output method="text" omit-xml-declaration="yes" standalone="yes" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="fig/label" />
<xsl:template match="fig/caption">
<xsl:text disable-output-escaping="yes">\caption{</xsl:text>
<xsl:apply-templates />
<xsl:text disable-output-escaping="yes">}</xsl:text>
</xsl:template>
<xsl:template match="fig/graphic">
<xsl:text disable-output-escaping="yes">\includegraphics{</xsl:text>
<xsl:apply-templates select="#href" />
<xsl:text disable-output-escaping="yes">.pdf}</xsl:text>
</xsl:template>
</xsl:stylesheet>
http://xsltransform.net/gVAjbT2
The <xsl:strip-space> element is used to define the elements for which white space should be removed. Preserving white space is the default setting, so using the element is only necessary if the <xsl:strip-space> element is used.
I need to transform a given XML to another format. This is the source:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://apple.com/itunes/importer" version="film5.1">
<provider>Provider</provider>
<language>de-DE</language>
<video>
<type>film</type>
<subtype>feature</subtype>
<vendor_id>some_id</vendor_id>
<country>US</country>
<original_spoken_locale>en</original_spoken_locale>
<title>Some movie title</title>
</video>
</package>
And this is the XSLT I tried:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:importer="http://apple.com/itunes/importer" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="importer:package">
<xsl:variable name="var-title">
<xsl:apply-templates select="video/title"/>
</xsl:variable>
<Movie>
<Title><xsl:value-of select="$var-title"/></Title>
</Movie>
</xsl:template>
</xsl:stylesheet>
But the <title> from source XML is not selected. What did I do wrong?
The namespace applies to the descendants as well so change <xsl:apply-templates select="video/title"/> to <xsl:apply-templates select="importer:video/importer:title"/> to use a prefix as well.
My real code is not this, but the problem that i am stating here applies to my real code.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book.child.1>
<title>charithram</title>
<author>sarika</author>
</book.child.1>
<book.child.2>
<title>doublebell</title>
<author>psudarsanan</author>
</book.child.2>
</books>
XSLT 1:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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:for-each select="books/*">
<newbook>
<title>
<xsl:value-of select="title" />
</title>
</newbook>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
There in no output generated for this XSLT. I am trying using online tool: http://www.freeformatter.com/xsl-transformer.html
I could not understand what was wrong, Finally when I modified the XSLT like as written below,
XSLT 2:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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="/">
<mytag>
<xsl:for-each select="books/*">
<newbook>
<title>
<xsl:value-of select="title" />
</title>
</newbook>
</xsl:for-each>
</mytag>
</xsl:template>
</xsl:stylesheet>
The output is generated in this case:
outputXML:
<?xml version="1.0" encoding="UTF-8"?>
<mytag>
<newbook>
<title>charithram</title>
</newbook>
<newbook>
<title>doublebell</title>
</newbook>
</mytag>
Can you please explain why is this behavior?
Also I don't know how exactly to ask this question, so please edit or let me know if i need to change the question title.
Your first XSLT will theoretically produce the output
<?xml version="1.0" encoding="UTF-8"?>
<newbook>
<title>charithram</title>
</newbook>
<newbook>
<title>doublebell</title>
</newbook>
But that output is not valid XML, because it has 2 root tags, which is not well-formed XML.
In this situation, you have probably the following choices
specify a root element like you did in XSLT 2
change the output from XML to TEXT, but be aware that any XML program will not be able to read the output
Here's a trivial but valid Docbook article:
<?xml version="1.0" encoding="utf-8"?>
<article xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>I Am Title</title>
<para>I am content.</para>
</article>
Here's a stylesheet that selects title if I remove the xmlns attribute above, and not if I leave it in:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:apply-templates select="article"/>
</xsl:template>
<xsl:template match="article">
<p><xsl:value-of select="title"/></p>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
How do I talk XPath into selecting title through article if it has that namespace attribute?
You need to add an alias for your namespace and use that alias in your XPath
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="http://docbook.org/ns/docbook"
exclude-result-prefixes="a"
>
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:apply-templates select="a:article"/>
</xsl:template>
<xsl:template match="a:article">
<p><xsl:value-of select="a:title"/></p>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>