Using the Translate function to remove newline cha

2019-08-03 05:40发布

问题:

Following the question- Removing all \n\r characters from a node XSLT? that looks to be solved, I am using this solution, but stumbled across this scenario-

What if we do not want the new line characters to be replaced in all the nodes. eg- Certain nodes like Description, Instructions are meant to store new lines if the user entered them on the webpage.

<T>
    <Name>Translate test</Name>
    <AlternateId>testid1</AlternateId>
    <Description>Translate test</Description>
    <Instructions>there is a new line between line1 and line2
    line1-asdfghjkl
    line2-asdfghjkl</Instructions>
    <Active>1</Active>
</T>

After using translate(.,' ',''), this is how the xml looks like now:

<T>
    <Name>Translate test</Name>
    <AlternateId>testid1</AlternateId>
    <Description>Translate test</Description>
    <Instructions>there is a new line between line1 and line2line1-asdfghjklline2-asdfghjkl</Instructions>
    <Active>1</Active>
</T>

I have >100 such tags that I don't want to be translated. Is there a way to ignore the translation of such unwanted tags? Any timely help would be greatly appreciated.

Regards, Ashish K

回答1:

Usually such a task is solved by starting with a template that copies nodes unchanged

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

Now you can add templates to transform the elements you want e.g.

<xsl:template match="Description | Instructions">
  <xsl:copy>
    <xsl:value-of select="translate(., '&#10;', '')"/>
  </xsl:copy>
</xsl:template>

Of course you would need to list all element names you want to be transformed in the match attribute but you don't have to spell out the names of elements you don't want to be transformed.



回答2:

You can filter elements in match attributes

<xsl:template match="*[name() = 'Instructions']/text()">
    <xsl:value-of select="translate(.,'&#xA;','')"/>
</xsl:template>

which means something like "only in Instruction element replace newline characters".

Edit:

You could make a external helper xml file containing names of elements indended for replacing.

<?xml version="1.0" encoding="UTF-8"?>
<Replace>
    <Description />
    <Instructions />
</Replace>

Load it into a variable by document() function

<xsl:variable name="elementsForReplacing" select="document('replaceNames.xml')/Replace/*" />

Then just check for presence in this variable for decision if replacing should be done.

<xsl:template match="text()">
    <xsl:variable name="elementName" select="name(..)" />
    <xsl:choose>
        <xsl:when test="$elementsForReplacing[name() = $elementName]">
            <xsl:value-of select="translate(.,'&#xA;','')"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="." />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>