当前位置: 首页 > 知识库问答 >
问题:

如何使用XSL从多个同名节点中创建一个节点?

戚奇略
2023-03-14
<Client>
  <Document>
    <service class="ABC">
      <author name="x"/>
      <Details>
        ...
      </Details>
    </service>
   </Document>
   <Document>
     <service class="ABC">
       <author name="x"/>
       <Details>
         ...
       </Details>
     </service>
   </Document>
   <Document>
     <service class="ABC">
       <author name="x"/>
       <Details>
         ...
       </Details>
     </service>
   </Document>'
</Client>
<Client>
  <Document>
    <service class="ABC">
      <author name="x"/>
       <Details>
         ...
       </Details>
    </service>
   </Document>
   <Document>
     <service class="ABC">
       <author name="x"/>
       <Details>
         ...
       </Details>
     </service>
   </Document>
   <Document>
     <service class="ABC">
       <author name="x"/>
       <Details>
         ...
       </Details>
     </service>
   </Document>'
   <component>
     <service class="ABC">
       <author name="x"/>
     </service>
   </component>'
</Client>
<xsl:template match="//v3:Client">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
      <component>
        <service class="">
          <xsl:apply-templates select="//v3:Client/v3:Document/v3:service/v3:author"/>
        </service>
      </component>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="//v3:Client/v3:component/v3:service">
    <xsl:element name="service" namespace="urn:hl7-org:v3">
      <xsl:attribute name="class">
        <xsl:value-of select="//v3:Client/v3:Document/v3:service/@class"/>
      </xsl:attribute>
    </xsl:element>
  </xsl:template>

但它没有提供所需的产出。它给出的输出像

Client
  Document
    service class="ABC"
      author name="x"
      details
        ...
      details
     service
    Document
   Document
    service class="ABC"
      author name="x"
      details
        ...
      details
    service
  Document
  Document
    service class="ABC"
      author name="x"
      details
        ...
      details
    service
  Document
  component
    service class=""
      author name="x"
    service
    service class=""
      author name="x"
    service
    service class=""
      author name="x"
    service
  component
Client

我是XSL的新手。有谁能帮我解决这个问题吗?

共有1个答案

曹旭
2023-03-14

如果希望在组件元素中输出不同的服务元素,那么在XSTL1.0中需要使用一种称为Muenchian分组的技术。我假设class属性唯一地标识了一个服务,所以您可以从定义一个键来查找服务开始,如下所示

<xsl:key name="service" match="service" use="@class" />

然后,在创建组件元素时,为了获得不同的服务元素,请查看所有这些元素,但只选择在其给定类属性的键中首先出现的元素。

<xsl:apply-templates 
     select="Document/service[generate-id() = generate-id(key('service', @class)[1])]" 
     mode="component" />

在与service元素匹配的模板中,您可以根据需要输出详细信息。在您的示例中,您似乎只需要author元素,而不需要详细信息。

<xsl:template match="service" mode="component">
   <xsl:copy>
     <xsl:apply-templates select="author|@*"/>
   </xsl:copy>
</xsl:template>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="service" match="service" use="@class" />

<xsl:template match="Client">
   <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
     <component>
        <xsl:apply-templates select="Document/service[generate-id() = generate-id(key('service', @class)[1])]" mode="component" />
     </component>
   </xsl:copy>
</xsl:template>

<xsl:template match="service" mode="component">
    <xsl:copy>
      <xsl:apply-templates select="author|@*"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>
<Client>
   <Document>
      <service class="ABC">
         <author name="x"/>
         <Details> ... </Details>
      </service>
   </Document>
   <Document>
      <service class="ABC">
         <author name="x"/>
         <Details> ... </Details>
      </service>
   </Document>
   <Document>
      <service class="ABC">
         <author name="x"/>
         <Details> ... </Details>
      </service>
   </Document>
   <component>
      <service class="ABC">
         <author name="x"/>
      </service>
   </component>
</Client>
 类似资料: