user533832
user533832

Reputation:

Multiple minor changes to a source XML document

I'm a complete newcomer to xslt. I'm trying to come up with a transformation that makes minor changes to a source xml document, eg from:

<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
  <file>
    <trans-unit>
      <source>Kodiak1 [[Name]]</source>
      <target></target>
    </trans-unit>
  </file>
</xliff>

to:

<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
  <file>
    <trans-unit>
      <source>Kodiak1 [[Name]]</source>
      <target>Kodiak1 <ph>Name</ph></target>
    </trans-unit>
  </file>
</xliff>

So far I've come up with:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="target">
    <target>
      <xsl:value-of select="preceding-sibling::source" /> 
    </target>
  </xsl:template>
</xsl:stylesheet>

Which copies the text from the <source> node to the <target> node but now I'm stuck - not least because if I add another <xsl:template match="..."> it matches on the original (eg , not on the new text - can you tell me what the next step should be?

Upvotes: 3

Views: 349

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="trans-unit[contains(source, '[[')]/target">
  <xsl:variable name="vS" select="../source"/>

  <target>
   <xsl:value-of select="substring-before($vS, '[')"/>
   <ph>
     <xsl:value-of select=
      "translate(substring-after($vS, '[['), ']','')"/>
   </ph>
  </target>
 </xsl:template>

 <xsl:template match="target">
  <target>
   <xsl:value-of select="../source"/>
  </target>
 </xsl:template>
</xsl:stylesheet>

when applied on the this XML document (the provided one made slightly more interesting):

<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
    <file>
        <trans-unit>
            <source>Kodiak1 [[Name]]</source>
            <target></target>
        </trans-unit>
        <trans-unit>
            <source>Kodiak2</source>
            <target></target>
        </trans-unit>
    </file>
</xliff>

produces the wanted, correct result:

<xliff xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
   <file>
      <trans-unit>
         <source>Kodiak1 [[Name]]</source>
         <target>Kodiak1 <ph>Name</ph>
         </target>
      </trans-unit>
      <trans-unit>
         <source>Kodiak2</source>
         <target>Kodiak2</target>
      </trans-unit>
   </file>
</xliff>

Explanation:

Appropriate use of templates and the standard XPath functions substring-before(), substring-after() and translate().

Upvotes: 5

Related Questions