如何使用 xslt 更改单个标签?

How to change a single tag with xslt?

在下面的结果中,OrderDetail 已替换为 baz。类似的 xslt 如何只改变第一次出现的 OrderDetail 而没有其他出现?

使用saxonb-xslt当前结果:

<?xml version="1.0" encoding="UTF-8"?>
<Order OrderID="10613">
  <CustomerID>HILAA</CustomerID>
  <EmployeeID>4</EmployeeID>
  <OrderDate>1997-07-29T05:38:16</OrderDate>
  <RequiredDate>1997-08-26T11:38:15</RequiredDate>
  <ShippedDate>1997-08-01T12:46:12</ShippedDate>
  <ShipVia>2</ShipVia>
  <Freight>8.1100</Freight>
  <ShipName>HILARION-Abastos</ShipName>
  <ShipAddress>Carrera 22 con Ave. Carlos Soublette #8-35</ShipAddress>
  <ShipCity>San Cristóbal</ShipCity>
  <ShipRegion>Táchira</ShipRegion>
  <ShipPostalCode>5022</ShipPostalCode>
  <ShipCountry>Venezuela</ShipCountry>
  <OrderDetails>
      <baz>
         <ProductID>13</ProductID>
         <UnitPrice>6.0000</UnitPrice>
         <Quantity>8</Quantity>
         <Discount>0.1</Discount>
      </baz>
      <baz>
         <ProductID>75</ProductID>
         <UnitPrice>7.7500</UnitPrice>
         <Quantity>40</Quantity>
         <Discount>0</Discount>
      </baz>
  </OrderDetails>
</Order>

来自这个 snippet 的一个更大的 xml 文件:

<Order OrderID="10613">
  <CustomerID>HILAA</CustomerID>
  <EmployeeID>4</EmployeeID>
  <OrderDate>1997-07-29T05:38:16</OrderDate>
  <RequiredDate>1997-08-26T11:38:15</RequiredDate>
  <ShippedDate>1997-08-01T12:46:12</ShippedDate>
  <ShipVia>2</ShipVia>
  <Freight>8.1100</Freight>
  <ShipName>HILARION-Abastos</ShipName>
  <ShipAddress>Carrera 22 con Ave. Carlos Soublette #8-35</ShipAddress>
  <ShipCity>San Cristóbal</ShipCity>
  <ShipRegion>Táchira</ShipRegion>
  <ShipPostalCode>5022</ShipPostalCode>
  <ShipCountry>Venezuela</ShipCountry>
  <OrderDetails>
    <OrderDetail>
      <ProductID>13</ProductID>
      <UnitPrice>6.0000</UnitPrice>
      <Quantity>8</Quantity>
      <Discount>0.1</Discount>
    </OrderDetail>
    <OrderDetail>
      <ProductID>75</ProductID>
      <UnitPrice>7.7500</UnitPrice>
      <Quantity>40</Quantity>
      <Discount>0</Discount>
    </OrderDetail>
  </OrderDetails>
</Order>

使用此 xslt 转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output indent="yes"/>


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

<xsl:template match="OrderDetail">
    <baz>
        <xsl:apply-templates/>
    </baz>
</xsl:template>

</xsl:stylesheet>

但是,这会更改所有匹配的节点名称。

第一个 <OrderDetail> 是前面没有 <OrderDetail> 的那个。

<xsl:template match="OrderDetail[not(preceding::OrderDetail)]">
    <baz>
        <xsl:apply-templates/>
    </baz>
</xsl:template>

无论嵌套如何,这都匹配整个文档中的第一个。

根据您定义的方式 "first",还有其他选项,例如match="OrderDetail[1]",匹配其各自父元素中的第一个