通过xslt中的子节点值创建父节点的副本

时间:2013-04-22 18:17:07

标签: xslt

以下是我的XML结构。

<Client>
  <Document>
    <service class="ABC">
      <author name="p"/>
      <title>t1</title>
      <Details>
        ...
      </Details>
    </service>
   </Document>
   <Document>
     <service class="XYZ">
       <author name="a"/>
       <title>t2</title>
       <Details>
         ...
       </Details>
     </service>
   </Document>
   <Document>
     <service class="PQR">
       <author name="x"/>
       <title>t3</title>
       <Details>
         ...
       </Details>
     </service>
   </Document>
</Client>

我想创建标题为't2'但无法找出解决方案的文档节点的副本。输出应该看起来像

<Client>
  <Document>
    <service class="ABC">
      <author name="p"/>
      <title>t1</title>
      <Details>
        ...
      </Details>
    </service>
   </Document>
   <Document>
     <service class="XYZ">
       <author name="a"/>
       <title>t2</title>
       <Details>
         ...
       </Details>
     </service>
   </Document>
   <Document>
     <service class="PQR">
       <author name="x"/>
       <title>t3</title>
       <Details>
         ...
       </Details>
     </service>
   </Document>
   <Document>
     <service class="XYZ">
       <author name="a"/>
       <title>t2</title>
       <Details>
         ...
       </Details>
     </service>
   </Document>
</Client>

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这个简单的样式表是这样做的一种方式:

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

  <!--
  Identity transform
  See http://en.wikipedia.org/wiki/Identity_transform#Using_XSLT
  -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Override identity transform to process <Client> element -->
  <xsl:template match="Client">
    <!-- Copy current element into output -->
    <xsl:copy>
      <!-- Apply attributes and child nodes -->
      <xsl:apply-templates select="@* | node()"/>
      <!-- Apply all <Document> elements with <title> whose value is "t2" -->
      <xsl:apply-templates select="Document[service/title = 't2']"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

以前的答案本来是正确的,但对于这行:

经过验证的正确版本是:

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

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

<!-- Override identity transform to process <Client> element -->
<xsl:template match="Client">
    <!-- Copy current element into output -->
    <xsl:copy>
        <!-- Apply attributes and child nodes -->
        <!-- Apply all <Document> elements with <title> whose value is "t2" -->
        <xsl:apply-templates select="Document[service/title = 't2']"/>
    </xsl:copy>
</xsl:template>

输出结果为:

<?xml version="1.0" encoding="utf-8"?>
<Client>
   <Document>
        <service class="XYZ">
            <author name="a"/>
            <title>t2</title>
            <Details>
               ...
            </Details>
        </service>
    </Document>
</Client>