I’m trying to replace this XML:
<name type="personal" authority="local">
<namePart>Gertrude</namePart>
<namePart type="termsOfAddress">Aunt</namePart>
<role>
<roleTerm authority="marcrelator" type="text">Correspondent</roleTerm>
<roleTerm authority="marcrelator" type="code">crp</roleTerm>
</role>
</name>
with this XML:
<name type="personal" authority="local">
<namePart>Aunt Gertrude</namePart>
<role>
<roleTerm authority="marcrelator" type="text">Correspondent</roleTerm>
<roleTerm authority="marcrelator" type="code">crp</roleTerm>
</role>
</name>
while still retaining the rest of the document. I’ve tried two methods: one that works, but seems stupid, and one that doesn’t work, and seems just as stupid.
First Method
<xsl:template match="* | processing-instruction() | comment()">
<xsl:copy>
<xsl:copy-of select="@*" copy-namespaces="no"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="//name/namePart[matches(., 'Gertrude')
and following-sibling::namePart[@type='termsOfAddress'
and matches(., 'Aunt')]]">
<namePart>Aunt Gertrude</namePart>
</xsl:template>
<xsl:template match="//name/namePart[@type='termsOfAddress'
and matches(., 'Aunt')
and preceding-sibling::namePart[matches(., 'Gertrude')]]"/>
Seoncd Method
<xsl:template match="* | processing-instruction() | comment()">
<xsl:copy>
<xsl:copy-of select="@*" copy-namespaces="no"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="//name[descendant::namePart[matches(., 'Gertrude')]
and descendant::namePart[@type='termsOfAddress'
and matches(., 'Aunt')]]/namePart">
<namePart>Aunt Gertrude</namePart>
</xsl:template>
So, like I said, the first one works, but having two separate templates to handle the two elements seemed somewhat redundant. So I tried the second method which gave me this:
<name type="personal" authority="local">
<namePart>Aunt Gertrude</namePart>
<namePart>Aunt Gertrude</namePart>
<role>
<roleTerm authority="marcrelator" type="text">Correspondent</roleTerm>
<roleTerm authority="marcrelator" type="code">crp</roleTerm>
</role>
</name>
Which is not what I want.
Is there any way to select both namePart elements and replace it with one?
This transformation:
when applied on the provided XML document:
produces the wanted, correct result: