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>

ドキュメントの残りの部分を保持しながら。私は 2 つの方法を試してみました。

最初の方法

<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>

前述したように、最初のテンプレートは機能しますが、2 つの要素を処理するために 2 つの別個のテンプレートを用意するのはやや冗長に思えました。だから私はこれを私に与えた2番目の方法を試しました:

<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 要素を選択して 1 つに置き換える方法はありますか?

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 に答える