【问题标题】:Faster way to transform this XML with XSLT?使用 XSLT 转换此 XML 的更快方法?
【发布时间】:2016-09-20 18:54:14
【问题描述】:

我完全是 XSLT 的菜鸟,我一直在环顾四周,并试图为此找到答案。下面的 XSLT 适用于我的小示例文件,但实际的 xml 文件为 200 mb,我等了 20 分钟才取消它。我的问题是,有没有更快的方法来做到这一点?我的 XSLT 是否草率?我在 Access 中使用它是因为我别无选择。

这是一个 XML 示例:

<?xml version="1.0" encoding="ISO-8859-1"?>
<ACES version="3.0">

<App action="A" id="1">
    <BaseVehicle id="119703">2013 Acura MDX                                                                                                 </BaseVehicle>
    <EngineBase id="5816">V6 3.7L (224cid 3664cc) 3.54x3.78in/90.0x96.0mm</EngineBase>
    <FuelType id="5">GAS</FuelType>
    <Qty>1</Qty>
</App>
<App action="A" id="2">
    <BaseVehicle id="119703">2013 Acura MDX                                                                                                 </BaseVehicle>
    <EngineBase id="2147">V6 3.7L (-cid 3664cc) 3.54x3.78in/90.0x96.0mm</EngineBase>
    <FuelType id="5">GAS</FuelType>
    <Qty>1</Qty>
</App>
</ACES>

这是我正在使用的 XSLT:

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="//ACES/App/BaseVehicle">
    <BaseID><xsl:value-of select="@id"/></BaseID>
    <BaseName><xsl:value-of select="//ACES/App/BaseVehicle"/></BaseName>
</xsl:template>

<xsl:template match="//ACES/App/EngineBase">
    <EngineID><xsl:value-of select="@id"/></EngineID>
    <EngineName><xsl:value-of select="//ACES/App/EngineBase"/></EngineName>
</xsl:template>

<xsl:template match="//ACES/App/FuelType">
    <FuelID><xsl:value-of select="@id"/></FuelID>
    <FuelName><xsl:value-of select="//ACES/App/FuelType"/></FuelName>
</xsl:template>

</xsl:stylesheet>

我真正想要的只是@id 和文本值。所以像:

BaseID   BaseVehicle       EngineID    EngineBase

119703   2013 Acura MDX     5816       V6 3.7L (224cid 3664cc) 3.54x3.78in/90.0x96.0mm

以第一个为例(我想要按此顺序列出所有内容)

有没有更快的方法可以做到这一点?

谢谢

【问题讨论】:

  • 您想要 XML 输出吗?那么请显示预期的xml,或者你想要文本,然后使用&lt;xsl:output method="text"/&gt;
  • 您的 XML 格式不正确 - BaseVehicle 结束标签在哪里?
  • @MichaelKay - BaseVehicle 的末端隐藏在右侧。我想知道这是否相当于大约 20Mb 的空白;-)
  • 不幸的是其他人为我制作了文件,所以我无能为力!

标签: xml ms-access xslt


【解决方案1】:

之所以需要这么长时间,是因为每次点击 BaseVehicle 时,例如,您都会处理文档中的每个 BaseVehicle:

<xsl:template match="//ACES/App/BaseVehicle">
    <BaseID><xsl:value-of select="@id"/></BaseID>
    <BaseName><xsl:value-of select="//ACES/App/BaseVehicle"/></BaseName>
</xsl:template>

几乎可以肯定是这样写的:

<xsl:template match="BaseVehicle">
    <BaseID><xsl:value-of select="@id"/></BaseID>
    <BaseName><xsl:value-of select="."/></BaseName>
</xsl:template>

(实际上,如果您使用的是 XSLT 1.0 处理器,那么select="//ACES/App/BaseVehicle" 只会输出第一个 BaseVehicle 的值,这可能会非常快或非常慢,具体取决于您的 XSLT 处理器的智能程度。但它不会需要多长时间并不重要,因为它会给出错误的输出。)

修正后,我希望这个样式表使用 Saxon 会在 10 秒左右运行。

【讨论】:

  • 这行得通。不幸的是,在 Access 中花了大约 10 分钟,但我可以处理。谢谢!
【解决方案2】:

您所写的内容将尝试输出所有内容,例如BaseVehicle的文本内容,只需要当前上下文节点之一即可。

我建议使用

<xsl:template match="App">
    <BaseID><xsl:value-of select="BaseVehicle/@id"/></BaseID>
    <BaseName><xsl:value-of select="BaseVehicle"/></BaseName>
    <EngineID><xsl:value-of select="EngineBase/@id"/></EngineId>
    <EngineName><xsl:value-of select="EngineBase"/></EngineName>
</xsl:template>

【讨论】:

  • 抱歉,我的意思是说我想要每个 BaseID 的列表,例如,而不仅仅是第一个。
  • 你试过代码了吗?它为每个应用程序提供一个。您当然不想要 all 并且对于下一个 App 再次 all ?!?
  • 是的,我试过了,当我使用它进行转换时,访问只返回 1 行数据。 Michael Kay 的建议对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多