0

我的 XML 结构就像

<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 文件包含

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

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

客户
  文档
    服务类="ABC"
      作者姓名="x"
      细节
        ...
      细节
     服务
    文档
   文档
    服务类="ABC"
      作者姓名="x"
      细节
        ...
      细节
    服务
  文档
  文档
    服务类="ABC"
      作者姓名="x"
      细节
        ...
      细节
    服务
  文档
  零件
    服务等级=""
      作者姓名="x"
    服务
    服务等级=""
      作者姓名="x"
    服务
    服务等级=""
      作者姓名="x"
    服务
  零件
客户

我是 xsl 的新手。有人可以帮我解决这个问题吗?

4

3 回答 3

0

使用group-by特点:

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

  <xsl:template match="/Client">

    <xsl:copy-of select="Document" />

    <!-- Group nodes by attribute value, produce one <component>
         per each group -->
    <xsl:for-each-group select="Document" group-by="service/@class">
      <component>
        <xsl:copy-of select="./service" />
      </component>
    </xsl:for-each-group>

  </xsl:template>

</xsl:stylesheet>

上面的样式表<component>为每个Document class=""属性值生成一个。

于 2013-03-26T09:43:41.410 回答
0

如果您无权访问,group-by可以考虑使用following-sibling::轴。

换句话说,您正在寻找这样的东西:

<component>
   <xsl:apply-templates select="Document/service[@class != following-sibling::service/@class]" mode="component" />
</component>

<xsl:template match="service" mode="component">
     <service class="{@class}">
         <!-- etc. -->
     </service>
</xsl:template>
于 2013-03-26T10:18:19.763 回答
0

如果您想在组件元素中输出不同的服务元素,那么在 XSTL1.0 中您需要使用一种称为Muenchian Grouping的技术。我假设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" />

在与服务元素匹配的模板中,您可以根据需要输出详细信息。在您的示例中,您似乎只需要此处的作者元素,而不是详细信息

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

使用mode是因为您只希望在输出 compenent 元素时匹配此模板。

这是完整的 XSLT

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

应用于您的示例 XML 时,将输出以下内容

<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>
于 2013-03-26T10:54:44.577 回答