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

我有这个输入 XML,我想在其中检查是否//To/Id包含 SERVICE。如果它包含 SERVICE 则应在<BPD>命名后添加一个元素<BON>SERVICE</BON>。另外我想检查我的输入 XML 是否已经包含<BON>元素,那么它的值应该被<Id>元素中的 SERVICE 替换。

我为此创建了一个模板->

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

该模板正在检查是否存在。如果它不存在,那么它会创建<BON> 元素并将“SERVICE”作为值添加到它。如果存在,那么它会再创建一个不需要的元素。我需要纠正我的第二次情况。

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为“SERVICE”且Role为“Commuter”的To元素,那么您要确保后面的BON元素的值为“SERVICE”(替换任何现有的,如果它已经存在)。

这可以不使用xsl:choose而是使用两个单独的匹配模板来完成。首先,您可以匹配具有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 回答