1
<To>
    <Id>SERVICE</Id>
    <Role>Commuter</Role>
</To>
<BPD>
    <OrgNo>234</OrgNo>      
</BPD>
<BON>123</BON>

I have this Input XML in which I want to check whether //To/Id contains SERVICE or not. If it contains SERVICE then a element should be added after <BPD> naming <BON>SERVICE</BON>. Also I want to check if my Input XML already contains <BON> element then its value should be replaced by SERVICE which is in <Id> element.

I have created a template for this ->

<xsl:template match="BPD">
 <xsl:choose>
   <xsl:when test="not(BON) and normalize-space(/To[Role='Commuter']/Id)='SERVICE'">
     <BON>
    <xsl:text>SERVICE</xsl:text>
     </BON>
   </xsl:when>          
   <xsl:when test="normalize-space(BON) and normalize-space(/To[Role='Commuter']/Id)='SERVICE'">
      <BON>
    <xsl:text>SERVICE</xsl:text>
      </BON>
    </xsl:when>
 </xsl:choose>
</xsl:template>

This template is checking whether exists or not. If it doesn't exist then it creates <BON> element and adds 'SERVICE' as value to it. And if exists then it creates one more element which is not required. I need to correct my second when situation.

4

2 に答える 2

2

既存のものを置き換えるだけの<BON>場合は、これだけが必要です。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*" name="ident">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="BPD[../To[Role='Commuter']/Id='SERVICE']">
    <xsl:call-template name="ident"/>
    <BON>SERVICE</BON>
  </xsl:template>

  <xsl:template match="BON[../To[Role='Commuter']/Id='SERVICE']"/>  

</xsl:stylesheet>

次のいずれかの入力を使用します。

<doc>
  <To>
    <Id>SERVICE</Id>
    <Role>Commuter</Role>
  </To>
  <BPD>
    <OrgNo>234</OrgNo>      
  </BPD>
  <BON>123</BON>  
</doc>

またはこの入力 (いいえ<BON>)

<doc>
  <To>
    <Id>SERVICE</Id>
    <Role>Commuter</Role>
  </To>
  <BPD>
    <OrgNo>234</OrgNo>      
  </BPD>
</doc>

次の出力が生成されます。

<doc>
   <To>
      <Id>SERVICE</Id>
      <Role>Commuter</Role>
   </To>
   <BPD>
      <OrgNo>234</OrgNo>
   </BPD>
   <BON>SERVICE</BON>
</doc>
于 2012-05-17T07:28:46.990 に答える
0

あなたが言っていることは、「サービス」のIDと「通勤者」の役割を持つTo要素がある場合、「サービス」の値を持つ次のBON要素があることを確認したいということです(すでに存在する場合は既存のもの)。

これは、xsl:chooseを使用せずに行うことができますが、2 つの別個の一致するテンプレートを使用します。まず、 BON要素があり、その前の要素が「Commuter」と「SERVICE」の場合に一致させることができます。

<xsl:template match="BON[preceding-sibling::To[Role='Commuter'][normalize-space(Id)='SERVICE']]">

次に、 BON要素がまったくないBPD要素に一致するテンプレートを作成できます。

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="BON[preceding-sibling::To[Role='Commuter'][normalize-space(Id)='SERVICE']]" name="bon">
      <BON>SERVICE</BON>
   </xsl:template>   

   <xsl:template match="BPD[preceding-sibling::To[Role='Commuter'][normalize-space(Id)='SERVICE']][not(following-sibling::BON)]">
      <xsl:call-template name="identity" />
      <xsl:call-template name="bon" />
   </xsl:template>

   <xsl:template match="@*|node()" name="identity">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

BON要素の重複コーディングを避けるために、名前付きテンプレートの使用に注意してください。

以下のXMLに当てはめると

<Root>
   <To>
      <Id>SERVICE</Id>
      <Role>Commuter</Role>
   </To>
   <BPD>
      <OrgNo>234</OrgNo>
   </BPD>
   <BON>123</BON>
</Root>

以下が出力されます

<Root>
   <To>
      <Id>SERVICE</Id>
      <Role>Commuter</Role>
    </To>
    <BPD>
       <OrgNo>234</OrgNo>
    </BPD>
    <BON>SERVICE</BON>
</Root>

入力 XML を次のように変更すると、この場合も同じ出力が生成されます。

<Root>
   <To>
      <Id>SERVICE</Id>
      <Role>Commuter</Role>
   </To>
   <BPD>
      <OrgNo>234</OrgNo>
   </BPD>
</Root>
于 2012-05-17T07:23:44.573 に答える