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!

2 Answers 2

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" />
Sign up to request clarification or add additional context in comments.

Comments

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

4 Comments

Thank you very much! I would still really want to know why the mentioned attribute prevents the <orth> element's content from being replaced. Can you perhaps explain?
@ 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 <entry> is a child of another node, let's say `<test>, 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?
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..
LingamurthyCS: thanks again! I edited my original question and it is now as it should initially have been, means I added all tags preceding <entry> (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, <orth> below <variant> 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!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.