【问题标题】:Can XSLT be improved further?XSLT 可以进一步改进吗?
【发布时间】:2016-08-17 06:05:05
【问题描述】:

我有 2 个 XSL:

获取 ID

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.1"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5"
                xmlns:oval-res="http://oval.mitre.org/XMLSchema/oval-results-5"
                xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5"
                xmlns:ind-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" 
                xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"
                xmlns:linux-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"
                exclude-result-prefixes="oval oval-def oval-res ind-def unix-def linux-def">
<xsl:output method="text" encoding="utf-8" />

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="oval-def:definition">
    <xsl:value-of select='@id'/>
    <xsl:text>&#xa;</xsl:text>
</xsl:template>

<!-- include to stop leakage from builtin templates -->
<xsl:template match='node()' mode='engine-results'/>
<xsl:template match="text()"/>

获取标题和结果

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.1"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5"
                xmlns:oval-res="http://oval.mitre.org/XMLSchema/oval-results-5"
                xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5"
                xmlns:ind-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" 
                xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix"
                xmlns:linux-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux"
                exclude-result-prefixes="oval oval-def oval-res ind-def unix-def linux-def">
<xsl:output method="text" encoding="utf-8" />

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="oval-def:definition">
    <xsl:if test="@id=$defid">
        <xsl:value-of select='oval-def:metadata/oval-def:title'/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:if>
</xsl:template>

<xsl:template match="oval-res:system/oval-res:definitions/oval-res:definition">
    <xsl:if test="@definition_id=$defid">
        <xsl:value-of select='@result'/>
    </xsl:if>
</xsl:template>

<!-- include to stop leakage from builtin templates -->
<xsl:template match='node()' mode='engine-results'/>
<xsl:template match="text()"/>

</xsl:stylesheet>

一些统计数据 源 XML 文件大约为 50 MB。 源文件中的 ID 数量为 2962。 我在 Linux 上使用 xsltproc。

我正在使用 python 程序首先从源 XML 中获取所有 ID。然后,对于每个 ID,从源 XML 中收集标题和状态。在具有 8 GB RAM 的 4 CPU 机器上,这种转换大约需要 2 个小时。

我的问题是,我可以做些什么来进一步改进 XSLT 以减少转换时间?

示例源文件

<?xml version="1.0" encoding="UTF-8"?>
<oval_results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns="http://oval.mitre.org/XMLSchema/oval-results-5" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-results-5 oval-results-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">
  <generator>
    <oval:product_name>cpe:/a:open-scap:oscap</oval:product_name>
    <oval:product_version>1.2.5</oval:product_version>
    <oval:schema_version>5.10</oval:schema_version>
    <oval:timestamp>2016-08-17T11:43:37</oval:timestamp>
  </generator>
  <directives>
    <definition_true reported="true" content="full"/>
    <definition_false reported="true" content="full"/>
    <definition_unknown reported="true" content="full"/>
    <definition_error reported="true" content="full"/>
    <definition_not_evaluated reported="true" content="full"/>
    <definition_not_applicable reported="true" content="full"/>
  </directives>
  <oval_definitions xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:unix-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix" xmlns:ind-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent" xmlns:lin-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#linux" xmlns="http://oval.mitre.org/XMLSchema/oval-definitions-5" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-definitions-5#unix unix-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#independent independent-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5#linux linux-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-definitions-5 oval-definitions-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">
    <generator>
      <oval:product_name>Enhanced SCAP Content Editor (eSCAPe)</oval:product_name>
      <oval:product_version>1.2.2</oval:product_version>
      <oval:schema_version>5.10</oval:schema_version>
      <oval:timestamp>2015-09-20T02:13:56</oval:timestamp>
    </generator>
    <definitions>
      <definition id="oval:com.vmware.test.linux:def:3" version="1" class="compliance">
        <metadata>
          <title>Rule 3 - /etc/passwd file is group-owned by root</title>
          <affected family="unix">
            <platform>cpe:/o:sles11:linux</platform>
          </affected>
          <description>This rule verifies that /etc/passwd file is group-owned by root.</description>
        </metadata>
        <criteria comment="None">
          <criterion test_ref="oval:com.vmware.test.linux:tst:3" comment="This rule verifies that /etc/passwd file is group-owned by root."/>
        </criteria>
      </definition>
      <definition id="oval:com.vmware.test.linux:def:2" version="1" class="compliance">
        <metadata>
          <title>Rule 2 - /etc/passwd file is owned by root</title>
          <affected family="unix">
            <platform>cpe:/o:sles11:linux</platform>
          </affected>
          <description>This rule verifies that /etc/passwd file is owned by root.</description>
        </metadata>
        <criteria comment="None">
          <criterion test_ref="oval:com.vmware.test.linux:tst:2" comment="This rule verifies that /etc/passwd file is owned by root."/>
        </criteria>
      </definition>
      <definition id="oval:com.vmware.test.linux:def:1" version="1" class="compliance">
        <metadata>
          <title>Rule 1 - /etc/passwd file has permissions of 644 or more restrictive</title>
          <affected family="unix">
            <platform>cpe:/o:sles11:linux</platform>
          </affected>
          <description>This rule verifies that /etc/passwd file has permissions of 644 or more restrictive.</description>
        </metadata>
        <criteria comment="None">
          <criterion test_ref="oval:com.vmware.test.linux:tst:1" comment="This rule verifies that /etc/passwd file has permissions of 644 or more restrictive."/>
        </criteria>
      </definition>
    </definitions>
    <tests>
      <unix-def:file_test id="oval:com.vmware.test.linux:tst:3" version="1" check="all" comment="Default comment, please change">
        <unix-def:object object_ref="oval:com.vmware.test.linux:obj:1"/>
        <unix-def:state state_ref="oval:com.vmware.test.linux:ste:3"/>
      </unix-def:file_test>
      <unix-def:file_test id="oval:com.vmware.test.linux:tst:2" version="1" check="all" comment="This rule verifies that /etc/passwd file is owned by root.">
        <unix-def:object object_ref="oval:com.vmware.test.linux:obj:1"/>
        <unix-def:state state_ref="oval:com.vmware.test.linux:ste:2"/>
      </unix-def:file_test>
      <unix-def:file_test id="oval:com.vmware.test.linux:tst:1" version="1" check="all" comment="This rule verifies that /etc/passwd file has permissions of 644 or more restrictive.">
        <unix-def:object object_ref="oval:com.vmware.test.linux:obj:1"/>
        <unix-def:state state_ref="oval:com.vmware.test.linux:ste:1"/>
      </unix-def:file_test>
    </tests>
    <objects>
      <unix-def:file_object id="oval:com.vmware.test.linux:obj:1" version="1" comment="/etc/passwd file">
        <unix-def:filepath>/etc/passwd</unix-def:filepath>
      </unix-def:file_object>
    </objects>
    <states>
      <unix-def:file_state id="oval:com.vmware.test.linux:ste:3" version="1" comment="This rule verifies that /etc/passwd file is group-owned by root.">
        <unix-def:group_id datatype="int">0</unix-def:group_id>
      </unix-def:file_state>
      <unix-def:file_state id="oval:com.vmware.test.linux:ste:2" version="1" comment="This rule verifies that /etc/passwd file is owned by root.">
        <unix-def:user_id datatype="int">0</unix-def:user_id>
      </unix-def:file_state>
      <unix-def:file_state id="oval:com.vmware.test.linux:ste:1" version="1" comment="This rule verifies that /etc/passwd file has permissions of 644 or more restrictive.">
        <unix-def:uexec datatype="boolean">false</unix-def:uexec>
        <unix-def:gwrite datatype="boolean">false</unix-def:gwrite>
        <unix-def:gexec datatype="boolean">false</unix-def:gexec>
        <unix-def:owrite datatype="boolean">false</unix-def:owrite>
        <unix-def:oexec datatype="boolean">false</unix-def:oexec>
      </unix-def:file_state>
    </states>
  </oval_definitions>
  <results>
    <system>
      <definitions>
        <definition definition_id="oval:com.vmware.test.linux:def:3" result="true" version="1">
          <criteria operator="AND" result="true">
            <criterion test_ref="oval:com.vmware.test.linux:tst:3" version="1" result="true"/>
          </criteria>
        </definition>
        <definition definition_id="oval:com.vmware.test.linux:def:2" result="true" version="1">
          <criteria operator="AND" result="true">
            <criterion test_ref="oval:com.vmware.test.linux:tst:2" version="1" result="true"/>
          </criteria>
        </definition>
        <definition definition_id="oval:com.vmware.test.linux:def:1" result="true" version="1">
          <criteria operator="AND" result="true">
            <criterion test_ref="oval:com.vmware.test.linux:tst:1" version="1" result="true"/>
          </criteria>
        </definition>
      </definitions>
      <tests>
        <test test_id="oval:com.vmware.test.linux:tst:1" version="1" check="all" result="true">
          <tested_item item_id="1312221" result="true"/>
        </test>
        <test test_id="oval:com.vmware.test.linux:tst:2" version="1" check="all" result="true">
          <tested_item item_id="1312221" result="true"/>
        </test>
        <test test_id="oval:com.vmware.test.linux:tst:3" version="1" check="all" result="true">
          <tested_item item_id="1312221" result="true"/>
        </test>
      </tests>
      <oval_system_characteristics xmlns:oval="http://oval.mitre.org/XMLSchema/oval-common-5" xmlns:unix-sys="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#unix" xmlns:ind-sys="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#independent" xmlns:lin-sys="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#linux" xmlns="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5" xsi:schemaLocation="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5 oval-system-characteristics-schema.xsd http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#independent independent-system-characteristics-schema.xsd http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#unix unix-system-characteristics-schema.xsd http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#linux linux-system-characteristics-schema.xsd http://oval.mitre.org/XMLSchema/oval-common-5 oval-common-schema.xsd">
        <generator>
          <oval:product_name>cpe:/a:open-scap:oscap</oval:product_name>
          <oval:schema_version>5.10</oval:schema_version>
          <oval:timestamp>2016-08-17T11:43:36</oval:timestamp>
        </generator>
        <system_info>
          <os_name>Linux</os_name>
          <os_version>#1 SMP Thu Mar 26 10:55:49 UTC 2015 (0e3c7c8)</os_version>
          <architecture>x86_64</architecture>
          <primary_host_name>vROPS_6-1</primary_host_name>
          <interfaces>
            <interface>
              <interface_name>lo</interface_name>
              <ip_address>127.0.0.1</ip_address>
              <mac_address>00:00:00:00:00:00</mac_address>
            </interface>
            <interface>
              <interface_name>lo</interface_name>
              <ip_address>127.0.0.2</ip_address>
              <mac_address>00:00:00:00:00:00</mac_address>
            </interface>
            <interface>
              <interface_name>eth0</interface_name>
              <ip_address>10.112.56.130</ip_address>
              <mac_address>00:50:56:93:61:59</mac_address>
            </interface>
            <interface>
              <interface_name>lo</interface_name>
              <ip_address>::1</ip_address>
              <mac_address>00:00:00:00:00:00</mac_address>
            </interface>
            <interface>
              <interface_name>eth0</interface_name>
              <ip_address>fe80::250:56ff:fe93:6159</ip_address>
              <mac_address>00:50:56:93:61:59</mac_address>
            </interface>
            <interface>
              <interface_name>sit0</interface_name>
              <ip_address>::10.112.56.130</ip_address>
              <mac_address>00:00:00:00:00:00</mac_address>
            </interface>
            <interface>
              <interface_name>sit0</interface_name>
              <ip_address>::127.0.0.2</ip_address>
              <mac_address>00:00:00:00:00:00</mac_address>
            </interface>
            <interface>
              <interface_name>sit0</interface_name>
              <ip_address>::127.0.0.1</ip_address>
              <mac_address>00:00:00:00:00:00</mac_address>
            </interface>
          </interfaces>
        </system_info>
        <collected_objects>
          <object id="oval:com.vmware.test.linux:obj:1" version="1" flag="complete">
            <reference item_ref="1312221"/>
          </object>
        </collected_objects>
        <system_data>
          <unix-sys:file_item id="1312221" status="exists">
            <unix-sys:filepath>/etc/passwd</unix-sys:filepath>
            <unix-sys:path>/etc</unix-sys:path>
            <unix-sys:filename>passwd</unix-sys:filename>
            <unix-sys:type>regular</unix-sys:type>
            <unix-sys:group_id datatype="int">0</unix-sys:group_id>
            <unix-sys:user_id datatype="int">0</unix-sys:user_id>
            <unix-sys:a_time datatype="int">1471360413</unix-sys:a_time>
            <unix-sys:c_time datatype="int">1471360395</unix-sys:c_time>
            <unix-sys:m_time datatype="int">1463992525</unix-sys:m_time>
            <unix-sys:size datatype="int">1254</unix-sys:size>
            <unix-sys:suid datatype="boolean">false</unix-sys:suid>
            <unix-sys:sgid datatype="boolean">false</unix-sys:sgid>
            <unix-sys:sticky datatype="boolean">false</unix-sys:sticky>
            <unix-sys:uread datatype="boolean">true</unix-sys:uread>
            <unix-sys:uwrite datatype="boolean">true</unix-sys:uwrite>
            <unix-sys:uexec datatype="boolean">false</unix-sys:uexec>
            <unix-sys:gread datatype="boolean">true</unix-sys:gread>
            <unix-sys:gwrite datatype="boolean">false</unix-sys:gwrite>
            <unix-sys:gexec datatype="boolean">false</unix-sys:gexec>
            <unix-sys:oread datatype="boolean">true</unix-sys:oread>
            <unix-sys:owrite datatype="boolean">false</unix-sys:owrite>
            <unix-sys:oexec datatype="boolean">false</unix-sys:oexec>
            <unix-sys:has_extended_acl datatype="boolean">false</unix-sys:has_extended_acl>
          </unix-sys:file_item>
        </system_data>
      </oval_system_characteristics>
    </system>
  </results>
</oval_results>

Python 程序的输出

[
    {
        "Status": "true",
        "Title": "Rule 3 - /etc/passwd file is group-owned by root",
        "RuleID": "oval:com.vmware.test.linux:def:3"
    },
    {
        "Status": "true",
        "Title": "Rule 2 - /etc/passwd file is owned by root",
        "RuleID": "oval:com.vmware.test.linux:def:2"
    },
    {
        "Status": "true",
        "Title": "Rule 1 - /etc/passwd file has permissions of 644 or more restrictive",
        "RuleID": "oval:com.vmware.test.linux:def:1"
    }
]

【问题讨论】:

  • 我认为要获得有意义的答案,您必须包含一些示例输入 XML 和相应的所需输出 XML。同时显示 COMPLETE xsllt 文件。
  • 我知道。我们需要查看实际样本。我也怀疑你需要使用两次通行证。阅读&lt;xsl:key.../&gt;key() 函数。
  • 将示例文件添加到问题中。
  • 50 MB 和 2962 个项目是非常小的数字。您应该在几秒钟内看到结果,而不是几小时。我也不明白为什么您需要分两次执行此操作。发布minimal reproducible example,包括输入和预期输出以获得更好的答案。
  • 好的,这是一个开始。对应的输出是什么?如果您需要帮助,您需要学会提供足够的信息,而无需我们零碎地从您那里提取信息。

标签: python xml xslt


【解决方案1】:

这样的东西对你有用吗?

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:oval-res="http://oval.mitre.org/XMLSchema/oval-results-5"
xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5"
exclude-result-prefixes="oval-def oval-res">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="result" match="oval-res:definition" use="@definition_id" />

<xsl:template match="/oval-res:oval_results">
    <output>
        <xsl:for-each select="oval-def:oval_definitions/oval-def:definitions/oval-def:definition">
            <def>
                <RuleID>
                    <xsl:value-of select="@id" />
                </RuleID>       
                <Title>
                    <xsl:value-of select="oval-def:metadata/oval-def:title"/>
                </Title>
                <Status>
                    <xsl:value-of select="key('result', @id)/@result"/>
                </Status>
            </def>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

为了便于测试,我已将此返回一个 XML 结果。应用于您的输入示例,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <def>
      <RuleID>oval:com.vmware.test.linux:def:3</RuleID>
      <Title>Rule 3 - /etc/passwd file is group-owned by root</Title>
      <Status>true</Status>
   </def>
   <def>
      <RuleID>oval:com.vmware.test.linux:def:2</RuleID>
      <Title>Rule 2 - /etc/passwd file is owned by root</Title>
      <Status>true</Status>
   </def>
   <def>
      <RuleID>oval:com.vmware.test.linux:def:1</RuleID>
      <Title>Rule 1 - /etc/passwd file has permissions of 644 or more restrictive</Title>
      <Status>true</Status>
   </def>
</output>

【讨论】:

  • 太棒了!像魅力一样工作!
  • @praving5 出于好奇:现在需要多长时间?
  • 数不过来!我想不到 5 秒!
  • Michael,我该如何为像 pastebin.com/VbMhcxVk 这样的 XML 文件做类似的事情。再次,我有兴趣选择 idref、结果和标题。我尝试按照您的示例进行操作,但无法做到。请帮忙。
  • @praving5 我建议您发布一个新问题,并在其中包含 XML 输入示例、您尝试的 XSLT 和预期结果。
猜你喜欢
  • 1970-01-01
  • 2018-03-23
  • 2012-11-26
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
相关资源
最近更新 更多