xsl转换:重命名标记(用于访问)

时间:2017-02-16 14:10:53

标签: xml xslt

我有一个要在Access中导入的xml文件。访问正在做得很好,除了它不喜欢有"。"在名字里。所以我基本上想要替换" netw.NetworkElement"在" NetworkElement"

这是一个示例输入

<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Header>
    <header xmlns="xmlapi_1.0">
        <requestID>client1:0</requestID>
        <requestTime>Feb 1, 2017 2:46:46 PM</requestTime>
        <responseTime>Feb 1, 2017 2:46:46 PM</responseTime>
    </header>
</SOAP:Header>
<SOAP:Body>
    <findResponse xmlns="xmlapi_1.0">
        <result>
            <netw.NetworkElement>
                <mgmtIpAddrType>ipv4</mgmtIpAddrType>
                <ipAddress>10.27.64.19</ipAddress>
                <baseMacAddress>C4-08-4A-07-97-C1</baseMacAddress>
                <systemAddress>10.27.64.19</systemAddress>
                <sysDescription>N/A</sysDescription>
                <outOfBandAddress>192.168.0.1</outOfBandAddress>
                <inBandSystemAddress>10.27.64.19</inBandSystemAddress>
                <inBandL3ManagementIf>0.0.0.0</inBandL3ManagementIf>
                <location>TL000075</location>
                <coordinates>10b, Shevchenko str., Tula</coordinates>
                <chassisType>sas_shelf_7210_m_24f2xfp_etr</chassisType>
                <productType>19</productType>
                <sysObjectId>.1.3.6.1.4.1.6527.6.2.1.2.2.3</sysObjectId>
                <latitudeInDegrees>0.0</latitudeInDegrees>
                <longitudeInDegrees>0.0</longitudeInDegrees>
                <neState>managed</neState>
                <locationId>0</locationId>
                <olcState>inService</olcState>
                <siteId>10.27.64.19</siteId>
                <deploymentState>0</deploymentState>
                <objectFullName>network:10.27.64.19</objectFullName>
                <name>10.27.64.19</name>
            </netw.NetworkElement>
            <netw.NetworkElement>
                <mgmtIpAddrType>ipv4</mgmtIpAddrType>
                <ipAddress>10.27.64.28</ipAddress>
                <baseMacAddress>C4-08-4A-07-1A-5D</baseMacAddress>
                <systemAddress>10.27.64.28</systemAddress>
                <sysDescription>N/A</sysDescription>
                <outOfBandAddress>192.168.2.3</outOfBandAddress>
                <inBandSystemAddress>10.27.64.28</inBandSystemAddress>
                <inBandL3ManagementIf>0.0.0.0</inBandL3ManagementIf>
                <location>TL000018</location>
                <coordinates>96, Sovetskaya av., Tula</coordinates>
                <chassisType>sas_shelf_7210_m_24f2xfp_etr</chassisType>
                <productType>19</productType>
                <sysObjectId>.1.3.6.1.4.1.6527.6.2.1.2.2.3</sysObjectId>
                <latitudeInDegrees>0.0</latitudeInDegrees>
                <longitudeInDegrees>0.0</longitudeInDegrees>
                <neState>managed</neState>
                <locationId>0</locationId>
                <olcState>inService</olcState>
                <siteId>10.27.64.28</siteId>
                <deploymentState>0</deploymentState>
                <objectFullName>network:10.27.64.28</objectFullName>
                <name>10.27.64.28</name>
            </netw.NetworkElement>
        </result>
    </findResponse>
</SOAP:Body>

这是预期的输出:

<NetworkElement>
                <mgmtIpAddrType>ipv4</mgmtIpAddrType>
                <ipAddress>10.27.64.19</ipAddress>
                <baseMacAddress>C4-08-4A-07-97-C1</baseMacAddress>
                <systemAddress>10.27.64.19</systemAddress>
                <sysDescription>N/A</sysDescription>
                <outOfBandAddress>192.168.0.1</outOfBandAddress>
                <inBandSystemAddress>10.27.64.19</inBandSystemAddress>
                <inBandL3ManagementIf>0.0.0.0</inBandL3ManagementIf>
                <location>TL000075</location>
                <coordinates>10b, Shevchenko str., Tula</coordinates>
                <chassisType>sas_shelf_7210_m_24f2xfp_etr</chassisType>
                <productType>19</productType>
                <sysObjectId>.1.3.6.1.4.1.6527.6.2.1.2.2.3</sysObjectId>
                <latitudeInDegrees>0.0</latitudeInDegrees>
                <longitudeInDegrees>0.0</longitudeInDegrees>
                <neState>managed</neState>
                <locationId>0</locationId>
                <olcState>inService</olcState>
                <siteId>10.27.64.19</siteId>
                <deploymentState>0</deploymentState>
                <objectFullName>network:10.27.64.19</objectFullName>
                <name>10.27.64.19</name>
            </NetworkElement>
            <NetworkElement>
                <mgmtIpAddrType>ipv4</mgmtIpAddrType>
                <ipAddress>10.27.64.28</ipAddress>
                <baseMacAddress>C4-08-4A-07-1A-5D</baseMacAddress>
                <systemAddress>10.27.64.28</systemAddress>
                <sysDescription>N/A</sysDescription>
                <outOfBandAddress>192.168.2.3</outOfBandAddress>
                <inBandSystemAddress>10.27.64.28</inBandSystemAddress>
                <inBandL3ManagementIf>0.0.0.0</inBandL3ManagementIf>
                <location>TL000018</location>
                <coordinates>96, Sovetskaya av., Tula</coordinates>
                <chassisType>sas_shelf_7210_m_24f2xfp_etr</chassisType>
                <productType>19</productType>
                <sysObjectId>.1.3.6.1.4.1.6527.6.2.1.2.2.3</sysObjectId>
                <latitudeInDegrees>0.0</latitudeInDegrees>
                <longitudeInDegrees>0.0</longitudeInDegrees>
                <neState>managed</neState>
                <locationId>0</locationId>
                <olcState>inService</olcState>
                <siteId>10.27.64.28</siteId>
                <deploymentState>0</deploymentState>
                <objectFullName>network:10.27.64.28</objectFullName>
                <name>10.27.64.28</name>
            </NetworkElement>

我已经阅读了这个论坛,尝试了不同的xsl转换,但我不了解xsl的工作原理。到目前为止,我只能复制输入文件: - (

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Template to match 'netw.NetworkElement' and replace with 'NetworkElement' -->
<xsl:template match="netw.NetworkElement">
    <NetworkElement>
        <xsl:apply-templates select="@*|node()" />
    </NetworkElement>
</xsl:template>

 <!-- Template to match all nodes, copy them and then apply templates to children. -->
<xsl:template match="@*|node()">
    <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

任何帮助都会非常感激

2 个答案:

答案 0 :(得分:0)

你大部分都是对的。您只需要考虑名称空间:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xapi="xmlapi_1.0"
                xmlns="xmlapi_1.0"
                exclude-result-prefixes="xapi">
    <!-- The namespace is declared twice here:

           - once with a prefix so that it can be referred to with XPath
             (xapi:netw.NetworkElement)

           - once without a prefix so that the <NetworkElement> element
             below is output in the correct namespace
    -->

    <!-- Template to match 'netw.NetworkElement' and replace with 'NetworkElement' -->
    <xsl:template match="xapi:netw.NetworkElement">
        <NetworkElement>
            <xsl:apply-templates select="@*|node()" />
        </NetworkElement>
    </xsl:template>

     <!-- Template to match all nodes, copy them and then apply templates to children. -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
       </xsl:copy>
    </xsl:template>
</xsl:stylesheet>  

解释这是如何工作的

正确匹配元素

在输入XML中,findResponse元素具有名称空间声明xmlns="xmlapi_1.0",这意味着它及其中的所有元素都在名称空间xmlapi_1.0中,除非另有说明。 / p>

您的XSLT具有match="netw.NetworkElement",但此XPath表达式(netw.NetworkElement)没有名称空间前缀,这意味着它与null名称空间中的元素匹配。您尝试重命名的元素在null命名空间中 not ,因此第一个xsl:template不会捕获任何内容。

要解决这个问题,我做了两件事:

  • 将命名空间声明xmlns:xapi="xmlapi_1.0"添加到样式表的顶部,以便我可以使用前缀xapi来引用此命名空间。
  • 修改match属性以使用此前缀:xapi:netw.NetworkElement

在此修改之后,您的XSLT将捕获netw.NetworkElement并重命名它,但仍然会有一个问题......

在正确的命名空间中输出NetworkElement

剩下的问题是默认情况下,NetworkElement将在null命名空间中输出,这意味着它将与所有其他元素具有不同的命名空间:

<findResponse xmlns="xmlapi_1.0">
    <result>
        <netw.NetworkElement xmlns="">
            <mgmtIpAddrType xmlns="xmlapi_1.0">ipv4</mgmtIpAddrType>
            <ipAddress xmlns="xmlapi_1.0">10.27.64.19</ipAddress>
            ...
        </netw.NetworkElement>
        <netw.NetworkElement xmlns="">
            ...
        </netw.NetworkElement>
    </result>
</findResponse>

我不认为我们想要这个,所以我通过在样式表的顶部添加名称空间声明xmlns="xmlapi_1.0"来解决这个问题。这使得默认情况下,任何元素文字(如<NetworkElement>)都将使用该命名空间而不是null命名空间输出。

输出中的xmlns:xapi="xmlapi_1.0"

正如您在评论中所观察到的那样,有一点奇怪,即NetworkElement在输出中有一个xmlns:xapi="xmlapi_1.0"名称空间声明。这不应该导致任何问题,但它也没有做任何有用的事情,所以有一种方法可以省略它:通过将属性exclude-result-prefixes="xapi"添加到样式表的顶部。这将确保除非必要,否则不会使用xapi声明。

答案 1 :(得分:0)

XSLT 1.0

使用此

ls > ls.log