2

I need to change the text of certain nodes, similar to Update the text of an element with XSLT based on param.

This is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
    <teiHeader>
        <fileDesc>
            <titleStmt>
                <title />
            </titleStmt>
            <publicationStmt>
                <p />
            </publicationStmt>
            <sourceDesc>
                <p />
            </sourceDesc>
        </fileDesc>
        <encodingDesc>
            <appInfo>
                <application ident="TEI_fromDOCX" version="2.15.0">
                    <label>DOCX to TEI</label>
                </application>
            </appInfo>
        </encodingDesc>
        <revisionDesc>
            <change>
                <date>$LastChangedDate: 2014-10-19$</date>
            </change>
        </revisionDesc>
    </teiHeader>
    <text>
        <body xml:id="test">
            <head>DICTIONARY</head>
            <entry>
                <form type="hyperlemma" xml:lang="cu">
                    <orth>абиѥ</orth>
                </form>
                <form type="lemma" xml:lang="cu">
                    <orth>абиѥ</orth>
                </form>
                <form type="variant" xml:lang="cu">
                    <orth>а̓бїе</orth>
                    <form type="hyperlemma" xml:lang="cu">
                        <orth>а̓бїе</orth>
                    </form>
                </form>
            </entry>
        </body>
    </text>
</TEI>

I now want to replace the text between <orth> in

<form type="variant" xml:lang="cu">
    <orth>а̓бїе</orth>
    <form type="hyperlemma" xml:lang="cu">
        <orth>а̓бїе</orth>
    </form>
</form>

by the content of <orth> in the previous node

<entry>
    <form type="hyperlemma" xml:lang="cu">
        <orth>абиѥ</orth>
    </form>

in order to get the following output:

<entry>
    <form type="hyperlemma" xml:lang="cu">
        <orth>абиѥ</orth>
    </form>
    <form type="lemma" xml:lang="cu">
        <orth>абиѥ</orth>      
    </form>
    <form type="variant" xml:lang="cu">
        <orth>а̓бїе</orth>
        <form type="hyperlemma" xml:lang="cu">
            <orth>абиѥ</orth>
        </form>
    </form>
 <entry>

When I use the following stylesheet

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" xpath-default-namespace="http://www.tei-c.org/ns/1.0" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:param name="replace_orth" select="entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />

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

<xsl:template match="form[@type='variant']/form[@type='hyperlemma' and @xml:lang='cu']/orth/text()">
    <xsl:value-of select="$replace_orth" />
</xsl:template>
</xsl:stylesheet>

then I get

<form type="variant" xml:lang="cu">
    <orth>а̓бїе</orth>
    <form type="hyperlemma" xml:lang="cu">
         <orth/>
</form>

So <orth> is empty. If I change the parameter to

<xsl:param name="replace_orth" select="'new orth'" />

'new orth' gets printed. But as the content of <entry><form type="hyperlemma" xml:lang="cu"><orth> is different for each entry (in the sample XML above I only show one entry), I cannot use a 'static' string.

What do I need to change?

Thanks for any hint!

Community
  • 1
  • 1
smo
  • 89
  • 8

2 Answers2

1

You've got to remove the attribute xpath-default-namespace="http://www.tei-c.org/ns/1.0" from xsl:stylesheet element. This attribute applies the mentioned uri as the namespace uri to all elements in xpaths, by default.

Example: If you run the following XML(a part from your input):

<entry>
<form type="hyperlemma" xml:lang="cu">
     <orth>value</orth>
</form>
</entry>

against this XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.tei-c.org/ns/1.0" version="2.0">
<xsl:output method="text" indent="yes" />
<xsl:param name="replace_orth" select="entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />

<xsl:template match="/">
    <xsl:value-of select="$replace_orth"/>
</xsl:template>
</xsl:stylesheet>

The output is nothing. The reason is all the xpath elements, by default, are supposed to have the namespace http://www.tei-c.org/ns/1.0. Thus teh param, replace_orth, selects nothing as the input XML doesn't have that namespace for any of its elements.

But, if you change your input XML to the following:

<entry xmlns="http://www.tei-c.org/ns/1.0">
<form type="hyperlemma" xml:lang="cu">
     <orth>value</orth>
</form>
</entry>

The output will be: value

And that's because the default namespace for all the elements in the input XML is http://www.tei-c.org/ns/1.0

Lingamurthy CS
  • 5,412
  • 2
  • 13
  • 21
  • Thank you very much! I would still really want to know why the mentioned attribute prevents the `` element's content from being replaced. Can you perhaps explain? – smo Nov 23 '14 at 15:52
  • @ LingamurthyCS thanks for your more detailed answer! I think I now understand what you meant. If I get rid of `http://www.tei-c.org/ns/1.0` in **both** the XML and the XSL and run it, I get, like you said 'value'. But as soon as `` is a child of another node, let's say `, the output again is nothing. That is what really puzzles me. Has that still to do with the namespace or is there something else interfering? – smo Nov 24 '14 at 10:09
  • Can you edit your question with what you tried? Or better, ask a new one if this is something new.. I didn't get what you meant.. – Lingamurthy CS Nov 24 '14 at 10:48
  • LingamurthyCS: thanks again! I edited my original question and it is now as it should initially have been, means I added all tags preceding `` (I omitted them as I would have never thought they were relevant). In the XML you actually have the namespace attribute that you suggested to delete in the stylesheet. If I run this (updated) XML against the stylesheet, `` below `` is empty then. (I unchecked the solved mark, not because I want to be mean but because your suggestion does not work for the updated question.) Thanks for your patience! – smo Nov 24 '14 at 15:22
1

The problem is that you're not selecting anything with your xsl:param. You'll either have to specify the full path to the orth or use //.

<xsl:param name="replace_orth" 
select="/TEI/text/body/entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />

or

<xsl:param name="replace_orth" 
select="//entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />
Daniel Haley
  • 51,389
  • 6
  • 69
  • 95