2

我正在尝试替换此 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')]]"/>

方法

    <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 元素并用一个替换它?

4

1 回答 1

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>
于 2012-09-08T02:30:06.237 回答