XSLT 用同级文本内容匹配的另一个文件“替换”值

XSLT “replace” values with another file matching by sibling text content

我正在寻求有关使用 XSLT 1.0 替换两个 XML 文件中的值的帮助。我相信我已经接近了,但需要一些指导来微调我目前所拥有的。

首先是问题: 这两个 XML 文件本质上是一样的。我正在用第二个文件及其所有子文件中的节点替换第一个文件中的两个节点,但我当前的实现是创建重复项。我确定这是因为我的 XPath 正在返回我给它的所有节点,但我不知道如何调整谓词,以便它仅在匹配兄弟节点时才替换 - 特别是 .

文件 1 - Networks.xml

<?xml version="1.0" encoding="utf-8"?>
<Network_Records xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Networks.xsd">
  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS1</SwitchName>
    <RackNumber>T5553</RackNumber>
    <Elevation>A14</Elevation>
    <RoomLocation>Phoenix</RoomLocation> 
   <NetworkSwitchConfigModule>switch_1_phx.txt</NetworkSwitchConfigModule>
    <Override>false</Override>
  </NetworkSwitch>

  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS2</SwitchName>
    <RackNumber>Fill</RackNumber>
    <Elevation>Fill</Elevation>
    <RoomLocation>Fill</RoomLocation>
   <NetworkSwitchConfigModule>switch_2_cle.txt</NetworkSwitchConfigModule>
    <Override>false</Override>
  </NetworkSwitch>

文件 2 - Networks_2.xml

<?xml version="1.0" encoding="utf-8"?>
<Network_Records xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Networks.xsd">
<NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS1</SwitchName>
    <RackNumber>Fill</RackNumber>
    <Elevation>Fill</Elevation>
    <RoomLocation>Fill</RoomLocation>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J5)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J5)</DeviceName>
      </NetworkPort>
    </NetworkModule>
  </NetworkSwitch>
  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS2</SwitchName>
    <RackNumber>REPLACE</RackNumber>
    <Elevation>REPLACE</Elevation>
    <RoomLocation>REPLACE</RoomLocation>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J4)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J7)</DeviceName>
      </NetworkPort>
    </NetworkModule>
  </NetworkSwitch>
</Network_Records>

到目前为止我的 XSLT -

<xsl:output method="xml" indent="yes" version="1.0" encoding="utf-8" />

<xsl:variable name="tempNetworks" select="document('Networks_2.xml')"/>

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

<xsl:template match="NetworkSwitchConfigModule">
   <xsl:copy-of select="$tempNetworks/Network_Records/NetworkSwitch/NetworkModule"/>
</xsl:template>

<xsl:template match="Override">
</xsl:template>

实际结果 - final.xml

<?xml version="1.0" encoding="utf-8"?>
<Network_Records xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Networks.xsd">
  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS1</SwitchName>
    <RackNumber>T5553</RackNumber>
    <Elevation>A14</Elevation>
    <RoomLocation>Phoenix</RoomLocation>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J5)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J5)</DeviceName>
      </NetworkPort>
    </NetworkModule>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J4)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J7)</DeviceName>
      </NetworkPort>
    </NetworkModule>
  </NetworkSwitch>

  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS2</SwitchName>
    <RackNumber>REPLACE</RackNumber>
    <Elevation>REPLACE</Elevation>
    <RoomLocation>REPLACE</RoomLocation>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J5)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J5)</DeviceName>
      </NetworkPort>
    </NetworkModule>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J4)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J7)</DeviceName>
      </NetworkPort>
    </NetworkModule>
  </NetworkSwitch>
</Network_Records>

预期结果 - final.xml

<?xml version="1.0" encoding="utf-8"?>
<Network_Records xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Networks.xsd">
  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS1</SwitchName>
    <RackNumber>T5553</RackNumber>
    <Elevation>A14</Elevation>
    <RoomLocation>Phoenix</RoomLocation>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J5)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J5)</DeviceName>
      </NetworkPort>
    </NetworkModule>
  </NetworkSwitch>

  <NetworkSwitch>
    <ChannelID>A</ChannelID>
    <SwitchName>OPS2</SwitchName>
    <RackNumber>REPLACE</RackNumber>
    <Elevation>REPLACE</Elevation>
    <RoomLocation>REPLACE</RoomLocation>
    <NetworkModule>
      <ModuleNumber>2</ModuleNumber>
      <NetworkPort>
        <PortNumber>1</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>ASA1 (J4)</DeviceName>
      </NetworkPort>
      <NetworkPort>
        <PortNumber>10</PortNumber>
        <DeviceType>Processor</DeviceType>
        <DeviceName>CWA2 (J7)</DeviceName>
      </NetworkPort>
    </NetworkModule>
  </NetworkSwitch>
</Network_Records>

只需将您的模板更改为

<xsl:template match="NetworkSwitchConfigModule">
    <xsl:copy-of select="$tempNetworks/Network_Records/NetworkSwitch[SwitchName = current()/../SwitchName]/NetworkModule"/>
</xsl:template>

<xsl:template match="Override" />

您缺少 select 第二个 XML 正确节点的谓词。因此,您复制了所有 NetworkModule 元素,而不仅仅是您想要的元素。谓词

SwitchName = current()/../SwitchName

比较第二个文件的SwitchName与当前匹配的模板规则的父SwitchName的值。