我正在尝试替换此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>
使用此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>
同时仍保留文件的其余部分。我尝试过两种方法:一种方法有效,但看起来很愚蠢,一种方法不起作用,看起来同样愚蠢。
第一种方法
<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方法
<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>
所以,就像我说的那样,第一个工作,但有两个单独的模板来处理这两个元素似乎有点多余。所以我尝试了第二种方法,它给了我这个:
<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>
这不是我想要的。
有没有办法选择两个namePart元素并用一个替换它?
答案 0 :(得分:0)
此转化:
<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="/*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<namePart>
<xsl:apply-templates select="namePart">
<xsl:sort select="count(@*)"/>
</xsl:apply-templates>
</namePart>
<xsl:apply-templates select="*[not(self::namePart)]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="namePart">
<xsl:if test="not(position()=1)"><xsl:text> </xsl:text></xsl:if>
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
应用于提供的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>
生成想要的正确结果:
<name type="personal" authority="local">
<namePart>Gertrude Aunt</namePart>
<role>
<roleTerm authority="marcrelator" type="text">Correspondent</roleTerm>
<roleTerm authority="marcrelator" type="code">crp</roleTerm>
</role>
</name>