Reputation: 637
I have an xml that has text within "word" elements e.g
<word>Police</word>
<word>confirmed</word>
<word>they are</word>
<word>questioning</word>
<word>a</word>
<word>man</word>
The problem is when I apply the xslt the text appears like "Policeconfirmedthey arequestioningaman".
Here is the xslt snippet that does this transform
<Paragraph>
<xsl:for-each select="./speaker/segment">
<xsl:value-of select="./nbest"/>
</xsl:for-each>
</Paragraph>
Can anyone offer any help as to how I can display this as "Police confirmed they are questioning a man"?
Many thanks.
Upvotes: 1
Views: 1178
Reputation: 1
By using normalize-space(), we can remove the whitespaces.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Identity template: copies everything as is -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Template to match <root> element and concatenate text content -->
<xsl:template match="root">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 7594
The reason they are running together is because the stylesheet is using a built-in template to match against which is collapsing the white space. I don't see where you are explicitly calling the <word/>
or surrounding XML, so I'm assuming it's an <xsl:apply-templates />
call somewhere. You should just need to just define a match template as such:
<xsl:template match="word">
<xsl:value-of select="." /> 
</xsl:template>
Whitespace is significant, so if in the above solution, you find it messing things up, you can wrap the within an <xsl:text/>
node, and whitespace be gone.
Then when the word node is matched you get it spaced. Note: there will be an extra space at the end. To get rid of that it will be slightly longer.
<xsl:temmplate match="word">
<xsl:value-of select="." />
<xsl:if test=". !=../word[last()]">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
This will only work when applying-templates, and not when using value-of or copy-of xsl directives.
Upvotes: 2
Reputation: 93
it is almost like "aku" answer. But "aku" answer creats one paragraph.
<xsl:for-each select="./speaker/segment">
<Paragraph>
<xsl:for-each select="./nbest/word"/>
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</Paragraph>
</xsl:for-each>
Upvotes: 2
Reputation: 123956
You can conditionally add a space between words based on word's position. The following snippet shows how to add a whitespace after all but last word.
<xsl:template match="//words">
<xsl:for-each select="word">
<xsl:value-of select="."/>
<!-- Check word's position -->
<xsl:if test="position()!=last()">
<!-- Add a whitespace if it's not the last word -->
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
If you produce HTML output, you can use info from this post to find out how to add a whitespace (instead of < xst:text > in my code snippet)
Upvotes: 4
Reputation: 75794
Add a space character.
Simple way:
<Paragraph>
<xsl:for-each select="./speaker/segment">
<xsl:value-of select="./nbest"/> 
</xsl:for-each>
</Paragraph>
Slightly more complex way to effectively trim the string:
<Paragraph>
<xsl:for-each select="./speaker/segment">
<xsl:if test="not(position() = 1)"> </xsl:if>
<xsl:value-of select="./nbest"/>
</xsl:for-each>
</Paragraph>
And some xpath ways: normalize-space, substring-before, substring-after in various forms.
Upvotes: 3