2016-01-22 75 views
0

我有以下的XML摘錄。完整的XML是OVF的定義。XSL修改基於命令行參數

<?xml version="1.0" encoding="UTF-8"?> 
<Envelope xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x xml:lang="en-US"> 
     <Item> 
     <rasd:Caption ovf:msgid="network.eth0.caption"/> 
     <rasd:Connection>eth0</rasd:Connection> 
     <rasd:Description ovf:msgid="network.eth0.description"/> 
     <rasd:ElementName>eth0</rasd:ElementName> 
     <rasd:InstanceID>13</rasd:InstanceID> 
     <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
     <rasd:ResourceType>10</rasd:ResourceType> 
     </Item> 
     <Item> 
     <rasd:Caption ovf:msgid="network.eth1.caption"/> 
     <rasd:Connection>eth1</rasd:Connection> 
     <rasd:Description ovf:msgid="network.eth1.description"/> 
     <rasd:ElementName>eth1</rasd:ElementName> 
     <rasd:InstanceID>14</rasd:InstanceID> 
     <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
     <rasd:ResourceType>10</rasd:ResourceType> 
     </Item> 
     <Item> 
     <rasd:Caption ovf:msgid="network.eth2.caption"/> 
     <rasd:Connection>eth2</rasd:Connection> 
     <rasd:Description ovf:msgid="network.eth2.description"/> 
     <rasd:ElementName>eth2</rasd:ElementName> 
     <rasd:InstanceID>15</rasd:InstanceID> 
     <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
     <rasd:ResourceType>10</rasd:ResourceType> 
     </Item> 
     <Item> 
     <rasd:Caption ovf:msgid="network.eth3.caption"/> 
     <rasd:Connection>eth3</rasd:Connection> 
     <rasd:Description ovf:msgid="network.eth3.description"/> 
     <rasd:ElementName>eth3</rasd:ElementName> 
     <rasd:InstanceID>16</rasd:InstanceID> 
     <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
     <rasd:ResourceType>10</rasd:ResourceType> 
     </Item>  
</Envelope> 

我想在<rasd:Connection>eth*</rasd:Connection>行之前插入行<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>但不是所有的人。到目前爲止,我已經得到了以下XSL並且它可以工作,但問題是我必須對每個要禁用的接口進行硬編碼。

<xsl:template match="rasd:Connection[text()='eth0']"> 
    <xsl:if test="$disableEths='true'"> 
     <xsl:element name="rasd:AutomaticAllocation">false</xsl:element> 
     <xsl:copy-of select="."/> 
    </xsl:if> 
</xsl:template> 
<xsl:template match="rasd:Connection[text()='eth1']"> 
    <xsl:if test="$disableEths='true'"> 
     <xsl:element name="rasd:AutomaticAllocation">false</xsl:element> 
     <xsl:copy-of select="."/> 
    </xsl:if> 
</xsl:template> 
<xsl:template match="rasd:Connection[text()='eth2']"> 
    <xsl:if test="$disableEths='true'"> 
     <xsl:element name="rasd:AutomaticAllocation">false</xsl:element> 
     <xsl:copy-of select="."/> 
    </xsl:if> 
</xsl:template> 

有沒有辦法有一個PARAM用戶通過包含他們想要禁用,如果沒有一個參數是輸入沒有禁用其中的任何值的分隔列表?如果它很重要,則使用xsltproc作爲處理器。

+1

是否有可能用戶傳入值列表的XML文件以禁用?然後,XSLT可以使用'document()'函數讀入以動態添加元素。 – Parfait

回答

2

作爲評價建議,如果用戶產生一個XML文件,命名爲例如DisableItems.xml像下面(其中的方式可以從文本分隔文件,txt文件,的.csv,.TAB來生產,等,使用通用的語言:C#,Java和Perl中,PHP,Python和R,VB ...):

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <disableitem>eth1</disableitem> 
    <disableitem>eth2</disableitem> 
    <disableitem>eth3</disableitem> 
</root> 

然後,XSLT可以相應地使用其document()功能進行搜索。要確保其他XML文件在同一目錄原始XML源:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
       xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

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

    <xsl:template match="rasd:Connection[text()=document('DisableItems.xml')/root/disableitem]"> 
    <xsl:element name="rasd:AutomaticAllocation">false</xsl:element> 
    <xsl:copy-of select="."/> 
    </xsl:template> 

</xsl:transform> 

輸出(中查找XML沒有規定通知的eth0沒有虛假元素)

<?xml version='1.0' encoding='UTF-8'?> 
<Envelope xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-US"> 
    <Item> 
    <rasd:Caption ovf:msgid="network.eth0.caption"/> 
    <rasd:Connection>eth0</rasd:Connection> 
    <rasd:Description ovf:msgid="network.eth0.description"/> 
    <rasd:ElementName>eth0</rasd:ElementName> 
    <rasd:InstanceID>13</rasd:InstanceID> 
    <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
    <rasd:ResourceType>10</rasd:ResourceType> 
    </Item> 
    <Item> 
    <rasd:Caption ovf:msgid="network.eth1.caption"/> 
    <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> 
    <rasd:Connection>eth1</rasd:Connection> 
    <rasd:Description ovf:msgid="network.eth1.description"/> 
    <rasd:ElementName>eth1</rasd:ElementName> 
    <rasd:InstanceID>14</rasd:InstanceID> 
    <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
    <rasd:ResourceType>10</rasd:ResourceType> 
    </Item> 
    <Item> 
    <rasd:Caption ovf:msgid="network.eth2.caption"/> 
    <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> 
    <rasd:Connection>eth2</rasd:Connection> 
    <rasd:Description ovf:msgid="network.eth2.description"/> 
    <rasd:ElementName>eth2</rasd:ElementName> 
    <rasd:InstanceID>15</rasd:InstanceID> 
    <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
    <rasd:ResourceType>10</rasd:ResourceType> 
    </Item> 
    <Item> 
    <rasd:Caption ovf:msgid="network.eth3.caption"/> 
    <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> 
    <rasd:Connection>eth3</rasd:Connection> 
    <rasd:Description ovf:msgid="network.eth3.description"/> 
    <rasd:ElementName>eth3</rasd:ElementName> 
    <rasd:InstanceID>16</rasd:InstanceID> 
    <rasd:ResourceSubType>VmxNet3</rasd:ResourceSubType> 
    <rasd:ResourceType>10</rasd:ResourceType> 
    </Item> 
</Envelope> 
+0

這是一個優雅的解決方案,我認爲我會與之合作。下次我啓動我的工作計算機時,我會對它進行測試。如果沒有找到該文件,它會不正常地失敗嗎?無論如何,我是否需要創建一個空文件? – stormbard

+0

應找不到文件,具體取決於XSLT處理器可能會出現錯誤。考慮一直保留一個文件,即使是空的根目錄。很高興我能幫上忙。 – Parfait

0

如果你在一個通過用逗號分隔值的列表的字符串,然後用xsltproc的,你可以使用EXSLT str:tokenize功能如下:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0" 
    xmlns:str="http://exslt.org/strings" 
    exclude-result-prefixes="str" 
    xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"> 

<xsl:output indent="yes"/> 

<xsl:param name="disableEths" select="'true'"/> 
<xsl:param name="con-to-change" select="'eth0,eth1,eth2'"/> 

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

<xsl:template match="rasd:Connection"> 
    <xsl:choose> 
    <xsl:when test=". = str:tokenize($con-to-change, ',') and $disableEths='true'"> 
     <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> 
     <xsl:copy-of select="."/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:call-template name="identity"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

</xsl:stylesheet> 

它當然希望使用該參數直接在匹配模式中,但在XSLT 1.0中不允許在匹配模式中使用變量或參數引用,我認爲xsltproc允許它,但在有match="rasd:Connection[. = str:tokenize($con-to-change, ',')]"的測試中,我得到了關於未定義變量的錯誤消息,所以上面將支票移入模板是我可以建議的。

+0

解決方案有效,但如果可能,我想遠離擴展功能。原因是儘可能保持輕量級和無依賴關係。 – stormbard