XSLT - 将元素转换为属性并包含兄弟节点中的元素

时间:2016-09-29 10:15:08

标签: xml xslt

我正在尝试使用XSLT转换XML文件以实现以下目标:

将节点的所有元素转换为该节点的属性,并在节点内包含节点外的元素。

让我更清楚一点,我将带领一个例子。 我的初始XML文件如下所示:

<?xml version="1.0" ?>
<queryResponse type="InventoryDetails" rootUrl="https://10.30.0.192/webacs/api/v1/data"
    requestUrl="https://10.30.0.192/webacs/api/v1/data/InventoryDetails?.full=true&amp;.firstResult=0&amp;.maxResults=1000"
    responseType="listEntityInstances" count="13" first="0" last="12">
    <entity url="https://10.30.0.192/webacs/api/v1/data/InventoryDetails/521521"
        type="InventoryDetails" dtoType="inventoryDetailsDTO">
        <inventoryDetailsDTO id="521521" displayName="521521">
        <deviceId>541541</deviceId>
        <ethernetInterfaces>
             <ethernetInterface>
                    <accessVlan>815</accessVlan>
                    <adminStatus>DOWN</adminStatus>
                    <allowedVlanIds>ALL</allowedVlanIds>
                    <desiredTrunkingEncapsulation>NEGOTIATE_OR_BEING_NEGOTIATED</desiredTrunkingEncapsulation>
                    <desiredVlanMode>ACCESS</desiredVlanMode>
                    <duplexMode>FULLDUPLEX</duplexMode>
                    <macAddress>6c:99:89:45:a4:8d</macAddress>
                    <mtu>1500</mtu>
                    <name>GigabitEthernet1/0/13</name>
                    <nativeVlan>1</nativeVlan>
                    <operationalStatus>DOWN</operationalStatus>
                    <operationalVlanMode>DOWN</operationalVlanMode>
                    <pruneEligibleVlanIds>2-1001</pruneEligibleVlanIds>
                    <speed>
                        <instanceId>0</instanceId>
                        <instanceVersion>0</instanceVersion>
                        <longAmount>1000000000</longAmount>
                    </speed>
                    <trunkingEncapsulationNegotiation>false</trunkingEncapsulationNegotiation>
                </ethernetInterface>
                <ethernetInterface>
                    <accessVlan>1</accessVlan>
                    <adminStatus>UP</adminStatus>
                    <allowedVlanIds>6,11</allowedVlanIds>
                    <desiredTrunkingEncapsulation>_8021Q</desiredTrunkingEncapsulation>
                    <desiredVlanMode>TRUNK</desiredVlanMode>
                    <duplexMode>FULLDUPLEX</duplexMode>
                    <macAddress>6c:99:89:45:a4:92</macAddress>
                    <mtu>1500</mtu>
                    <name>GigabitEthernet1/0/18</name>
                    <nativeVlan>1</nativeVlan>
                    <operationalStatus>UP</operationalStatus>
                    <operationalTrunkEncapsulation>_8021Q</operationalTrunkEncapsulation>
                    <operationalVlanMode>TRUNK</operationalVlanMode>
                    <pruneEligibleVlanIds>2-1001</pruneEligibleVlanIds>
                    <speed>
                        <instanceId>0</instanceId>
                        <instanceVersion>0</instanceVersion>
                        <longAmount>1000000000</longAmount>
                    </speed>
                    <trunkingEncapsulationNegotiation>true</trunkingEncapsulationNegotiation>
                </ethernetInterface>
                <modules>
                <module>
                    <description>Switch 2 - WS-C3750X-48 - Fixed Module 0</description>
                    <equipmentId>546563</equipmentId>
                    <equipmentType>MODULE</equipmentType>
                    <operationStatus>ok</operationStatus>
                    <physicalLocation>WS-C3750X-48</physicalLocation>
                    <productName>Switch 2 - WS-C3750X-48 - Fixed Module 0</productName>
                    <softwareVersion>15.0(2)SE7</softwareVersion>
                    <vendorType>cevModuleCat3750x48</vendorType>
                </module>
                <module>
                    <description>FRULink 10G SM Module</description>
                    <equipmentId>546565</equipmentId>
                    <equipmentType>MODULE</equipmentType>
                    <operationStatus>ok</operationStatus>
                    <physicalLocation>FRULink Container</physicalLocation>
                    <productName>Switch 2 - FRULink Slot 1 - FRULink Module</productName>
                    <softwareVersion>15.0(2)SE7</softwareVersion>
                    <vendorType>cevC3KxSm10g</vendorType>
                </module>
            </modules>
            </ethernetInterfaces>
        </inventoryDetailsDTO>
    </entity>
</queryResponse>

我的结果需要如下:

<Data>
  <ethernetInterface deviceID="xxx" accessVlan="xxxx" adminStatus="xxxx"/>
  <ethernetInterface devideID="xxx" accessVlan="xxxx" adminStatus="xxxx"/>
</Data>

这基本上适用于<entity>节点内的每个节点和所有属性。 虽然我可以正确地格式化一些数据但是我得到的太多了(它只是格式化我指定的,其余的仍然被复制但没有格式化)而且你看到的DeviceID不在我所知的节点内从单独的兄弟节点获取属性。

1 个答案:

答案 0 :(得分:0)

试试这是你的出发点:

XSLT 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="/queryResponse">
    <Data>
        <xsl:for-each select="entity/inventoryDetailsDTO/ethernetInterfaces/ethernetInterface">
            <ethernetInterface deviceID="{../../deviceId}">
                <xsl:for-each select="accessVlan | adminStatus">
                    <xsl:attribute name="{name()}">
                        <xsl:value-of select="." />
                    </xsl:attribute>
                </xsl:for-each>
            </ethernetInterface>
        </xsl:for-each>
    </Data>
</xsl:template>

</xsl:stylesheet>

注意

  1. XML区分大小写; deviceIDdeviceId;
  2. 不同
  3. deviceId不在“单独的兄弟节点”中;它是在“叔叔”(祖父母的孩子)节点。正确缩进输入XML可能会有所帮助。