使用VM config中的XSL查询选择特定值

时间:2014-03-20 19:28:05

标签: xml parsing xslt

我正在尝试使用XSL文件从XML文档中提取特定值。我试图提取的值是在密钥节点下,其中key必须包含值CIMHttpsServer。如果它包含我想继续打印信息的值,否则不打印任何内容。我试图搜索它,这是我已经得到的。如果您看到我的错误,请提供帮助。

文件运行正常,直到我开始调整它以返回特定值;现在它执行但什么都不返回。

    <?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:audit="urn:internalvim25">

<xsl:template match="audit:returnval">

<xsl:for-each select="audit:propSet/audit:val[@xsi:type='HostConfigInfo']/audit:firewall/audit:ruleset/audit:key">

<xsl:if test="key[text()='CIMHttpsServer']">

Key <xsl:value-of select="audit:key"/>
Label <xsl:value-of select="audit:label"/>
Required <xsl:value-of select="audit:required"/>
Rule
-Port <xsl:value-of select="audit:rule/audit:port"/>
-Direction <xsl:value-of select="audit:rule/audit:direction"/>
-Protocol <xsl:value-of select="audit:rule/audit:protocol"/>
Enabled <xsl:value-of select="audit:enabled"/>

</xsl:if>

</xsl:for-each>

</xsl:template>

</xsl:stylesheet>

这是正在使用的XML文件的片段。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <RetrievePropertiesResponse xmlns="urn:internalvim25">
      <returnval>
        <obj type="HostSystem" serverGuid="165246FF-D519-4F4F-A52E-1AF1D0866BA7">host-28</obj>
        <propSet>
          <name>alarmActionsEnabled</name>
          <val xsi:type="xsd:boolean">true</val>
        </propSet>
        <propSet>
          <name>availableField</name>
          <val xsi:type="ArrayOfCustomFieldDef" />
        </propSet>
        <propSet>
          <name>capability</name>
          <val xsi:type="HostCapability">
            <recursiveResourcePoolsSupported>true</recursiveResourcePoolsSupported>
            <cpuMemoryResourceConfigurationSupported>true</cpuMemoryResourceConfigurationSupported>
            <rebootSupported>true</rebootSupported>
            <shutdownSupported>true</shutdownSupported>
            <vmotionSupported>true</vmotionSupported>
            <standbySupported>true</standbySupported>
            <ipmiSupported>true</ipmiSupported>
            <maxSupportedVMs>1200</maxSupportedVMs>
            <maxRunningVMs>0</maxRunningVMs>
            <maxSupportedVcpus>8</maxSupportedVcpus>
            <datastorePrincipalSupported>true</datastorePrincipalSupported>
            <sanSupported>true</sanSupported>
            <nfsSupported>true</nfsSupported>
            <iscsiSupported>true</iscsiSupported>
            <vlanTaggingSupported>true</vlanTaggingSupported>
            <nicTeamingSupported>true</nicTeamingSupported>
            <highGuestMemSupported>true</highGuestMemSupported>
            <maintenanceModeSupported>true</maintenanceModeSupported>
            <suspendedRelocateSupported>true</suspendedRelocateSupported>
            <restrictedSnapshotRelocateSupported>true</restrictedSnapshotRelocateSupported>
            <perVmSwapFiles>true</perVmSwapFiles>
            <localSwapDatastoreSupported>true</localSwapDatastoreSupported>
            <unsharedSwapVMotionSupported>true</unsharedSwapVMotionSupported>
            <backgroundSnapshotsSupported>false</backgroundSnapshotsSupported>
            <preAssignedPCIUnitNumbersSupported>true</preAssignedPCIUnitNumbersSupported>
            <screenshotSupported>true</screenshotSupported>
            <scaledScreenshotSupported>true</scaledScreenshotSupported>
            <storageVMotionSupported>true</storageVMotionSupported>
            <vmotionWithStorageVMotionSupported>false</vmotionWithStorageVMotionSupported>
            <recordReplaySupported>false</recordReplaySupported>
            <ftSupported>false</ftSupported>
            <replayUnsupportedReason>incompatibleCpu</replayUnsupportedReason>
            <ftCompatibilityIssues>haAgentIssue</ftCompatibilityIssues>
            <ftCompatibilityIssues>incompatibleCpu</ftCompatibilityIssues>
            <ftCompatibilityIssues>missingFTLoggingNic</ftCompatibilityIssues>
            <ftCompatibilityIssues>missingVMotionNic</ftCompatibilityIssues>
            <loginBySSLThumbprintSupported>true</loginBySSLThumbprintSupported>
            <cloneFromSnapshotSupported>true</cloneFromSnapshotSupported>
            <deltaDiskBackingsSupported>true</deltaDiskBackingsSupported>
            <perVMNetworkTrafficShapingSupported>false</perVMNetworkTrafficShapingSupported>
            <tpmSupported>false</tpmSupported>
            <virtualExecUsageSupported>true</virtualExecUsageSupported>
            <storageIORMSupported>true</storageIORMSupported>
            <vmDirectPathGen2Supported>false</vmDirectPathGen2Supported>
            <vmDirectPathGen2UnsupportedReason>hostNptIncompatibleHardware</vmDirectPathGen2UnsupportedReason>
            <vmDirectPathGen2UnsupportedReason>hostNptDisabled</vmDirectPathGen2UnsupportedReason>
            <vStorageCapable>true</vStorageCapable>
          </val>
        </propSet>
        <propSet>
          <name>config</name>
          <val xsi:type="HostConfigInfo">

...<snip>...

<firewall>
              <defaultPolicy>
                <incomingBlocked>false</incomingBlocked>
                <outgoingBlocked>true</outgoingBlocked>
              </defaultPolicy>
              <ruleset>
                <key>CIMHttpServer</key>
                <label>CIM Server</label>
                <required>false</required>
                <rule>
                  <port>5988</port>
                  <direction>inbound</direction>
                  <protocol>tcp</protocol>
                </rule>
                <enabled>true</enabled>
              </ruleset>
              <ruleset>
                <key>CIMHttpsServer</key>
                <label>CIM Secure Server</label>
                <required>false</required>
                <rule>
                  <port>5989</port>
                  <direction>inbound</direction>
                  <protocol>tcp</protocol>
                </rule>
                <enabled>true</enabled>
              </ruleset>

期望的输出:

Key CIMHttpsServer
Label CIM Secure Server
Required false
Rule
-Port 5989
-Direction inbound
-Protocol tcp
Enabled true

2 个答案:

答案 0 :(得分:1)

你的方法太复杂了。尝试更模块化的方法:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:audit="urn:internalvim25"
    exclude-result-prefixes="audit xsi soap"
>
  <xsl:output type="text" />
  <xsl:variable name="NL" select="'&#xA;'" />

  <xsl:template match="/">
    <xsl:apply-templates select=".//*[audit:key = 'CIMHttpsServer']" />
  </xsl:template>

  <xsl:template match="audit:ruleset">
    <xsl:value-of select="concat('Key: ', audit:key, $NL)" />
    <xsl:value-of select="concat('Label: ', audit:label, $NL)" />
    <xsl:value-of select="concat('Required: ', audit:required, $NL)" />
    <xsl:apply-templates select="audit:rule" />
    <xsl:value-of select="concat('Enabled: ', audit:enabled, $NL)"/>
  </xsl:template>

  <xsl:template match="audit:rule">
    <xsl:value-of select="concat('Rule', $NL)" />
    <xsl:value-of select="concat('-Port: ', audit:port, $NL)" />
    <xsl:value-of select="concat('-Direction: ', audit:direction, $NL)" />
    <xsl:value-of select="concat('-Protocol: ', audit:protocol, $NL)" />
  </xsl:template>
</xsl:stylesheet>

注释

  • 避免输出&#34;无人看守&#34;文本。像我一样使用<xsl:value-of><xsl:text>。您的源代码看起来会更清晰(因为您可以正确缩进)并且您可以更轻松地格式化输出。
  • 使用模板匹配。不要将整个处理逻辑塞进一个具有N个嵌套级别的大模板中。
  • 如果要输出纯文本,请使用适当的输出模式。
  • 如果您不输出纯文本并希望保持输入命名空间不会出现在输出中,请使用exclude-result-prefixes。但是,总是有启用它并没有什么坏处。
  • 您不需要声明您不打算使用的命名空间。 soapxsi对您的样式表没有影响,您可以省略它们。

答案 1 :(得分:1)

我建议你在XSLT中开始使用Identity template。如果这样做,您可以使用以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:audit="urn:internalvim25">
    <xsl:output method="text" encoding="UTF-8" />

    <xsl:variable name="lf" select="'&#10;'" />

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

    <xsl:template match="audit:ruleset[audit:key = 'CIMHttpsServer']">
        <xsl:text>Key </xsl:text><xsl:value-of select="audit:key"/><xsl:value-of select="$lf" />
        <xsl:text>Label </xsl:text><xsl:value-of select="audit:label"/><xsl:value-of select="$lf" />
        <xsl:text>Required </xsl:text><xsl:value-of select="audit:required"/><xsl:value-of select="$lf" />
        <xsl:text>Rule</xsl:text><xsl:value-of select="$lf" />
        <xsl:text>-Port </xsl:text><xsl:value-of select="audit:rule/audit:port"/><xsl:value-of select="$lf" />
        <xsl:text>-Direction </xsl:text><xsl:value-of select="audit:rule/audit:direction"/><xsl:value-of select="$lf" />
        <xsl:text>-Protocol </xsl:text><xsl:value-of select="audit:rule/audit:protocol"/><xsl:value-of select="$lf" />
        <xsl:text>Enabled </xsl:text><xsl:value-of select="audit:enabled"/><xsl:value-of select="$lf" />
    </xsl:template>
</xsl:stylesheet>

这将产生所需的输出。如果您不想使用身份转换并保持XSLT更像现在,我建议删除xsl:if并将测试添加到xsl:for-each,如下所示:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:audit="urn:internalvim25">
    <xsl:template match="audit:returnval">
        <xsl:for-each select="audit:propSet/audit:val[@xsi:type='HostConfigInfo']/audit:firewall/audit:ruleset[audit:key = 'CIMHttpsServer']">
Key <xsl:value-of select="audit:key"/>
Label <xsl:value-of select="audit:label"/>
Required <xsl:value-of select="audit:required"/>
Rule
-Port <xsl:value-of select="audit:rule/audit:port"/>
-Direction <xsl:value-of select="audit:rule/audit:direction"/>
-Protocol <xsl:value-of select="audit:rule/audit:protocol"/>
Enabled <xsl:value-of select="audit:enabled"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>