【问题标题】:Filtering most out of XML with XSL?使用 XSL 过滤大部分 XML?
【发布时间】:2010-10-18 18:51:57
【问题描述】:

我需要将大量 XML 文件(Fedora 导出)转换为不同类型的 XML。尝试使用 XSL 样式表并使用 msxsl 转换器进行检查。

假设我有这样的 xml 文件(假设在 AAA、OBJ、amd 所有其他节点中实际上还有其他节点),Source.XML:

<DOC>
<AAA>
    <STUFF>example</STUFF>
    <OBJ>
        <OBJVERS id="A1" CREATED="2008-02-18T13:28:08.245Z"/>
        <OBJVERS id="A2" CREATED="2008-02-19T10:42:41.965Z"/>
        <OBJVERS id="A13" CREATED="2009-03-16T12:43:11.703Z"/>
    </OBJ>
</AAA>
<FFF/>
<GGG/>
<DDD>
    <FILE />
</DDD>
</DOC>

我需要看起来像这样(Target.XML):

    <MYOBJ>
      <ELEM>contents of OBJVERS with the biggest id OR 
creation date (whichever is easier to do) go here</ELEM>
      <IMAGE> contents of <FILE> node go here</IMAGE>
    </MYOBJ>

我遇到的主要问题是,由于我是 XSL 新手(对于这个特定任务,没有足够的时间来正确学习它)是我无法理解如何告诉 XSL 处理器不要处理其他任何东西,例如,我不断从 获取输出。

更新:基本上,我同时解决了这个问题。我将发布我自己的答案并关闭问题。

Update2:好的,安德鲁的回答也有效,所以我只是接受它。 :)

【问题讨论】:

  • -1。 Stackoverflow 并不是一个真正可以说 RTFM 的地方,但您基本上只是要求社区为您编写代码,如果您阅读免费提供的文档就可以编写这些代码。所以,详细一点 - 你有什么问题?
  • 好吧。我在来这里之前阅读了 RTFM,但好吧,很公平......我会解释更多。

标签: xml xslt


【解决方案1】:

这个问题的表述非常松散,这无助于提供更有意义的解决方案

这就是说,下面的变换

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

    <xsl:template match="/">
      <MYOBJ>
        <ELEM>
           <xsl:for-each select="/*/AAA/OBJ/OBJVERS">
             <xsl:sort select="@CREATED" order="descending"/>

             <xsl:if test="position() = 1">
                <xsl:copy-of select="."/>
             </xsl:if>
           </xsl:for-each>
        </ELEM>

        <IMAGE>
          <xsl:copy-of select="/*/DDD/FILE"/>
        </IMAGE>
      </MYOBJ>
    </xsl:template>
</xsl:stylesheet>

应用于人工提供的 XML 文档时(事实上,它的结构和命名很糟糕,违反了许多设计 XML 文档的原则):

<DOC>
    <AAA>
        <STUFF>example</STUFF>
        <OBJ>
            <OBJVERS id="A1" CREATED="2008-02-18T13:28:08.245Z"/>
            <OBJVERS id="A2" CREATED="2008-02-19T10:42:41.965Z"/>
            <OBJVERS id="A13" CREATED="2009-03-16T12:43:11.703Z"/>
        </OBJ>
    </AAA>
    <FFF/>
    <GGG/>
    <DDD>
        <FILE />
    </DDD>
</DOC>

产生人们可以猜到的结果

<MYOBJ>
   <ELEM>
      <OBJVERS id="A13" CREATED="2009-03-16T12:43:11.703Z"/>
   </ELEM>
   <IMAGE>
      <FILE/>
   </IMAGE>
</MYOBJ>

【讨论】:

  • 非常感谢您的时间和回答。顺便说一句,人为设计的 XML 是 Fedora Commons 软件在您尝试导出其中包含的数字对象时生成的(相当简化的版本,但结构上是正确的)。
  • @Gnudiff 很高兴答案很有帮助。我不敢相信任何有用的 XML 词汇表都会包含名为“AAA”、“DDD”、“FFF”和“GGG”的元素。
  • @Dimitre:不,AAA/BBB 标签的命名是我的,这是真的,我只想提请注意文档中相关的部分,并且已阅读 zvon.org最近在他们的例子中使用了这样的标签,所以我有点迷上了。这是真的,然而,OBJVERS 的版本标签不是简单的数字,而是出于某种奇怪的原因具有字母数字前缀。
  • @Gnudiff 我不认为 zvon.org 是 XML/XSLT 世界的权威。任何尊重这门学科的人都需要一本经典作者——Michael Kay 和/或 Jeni Tennison 的好书。
【解决方案2】:

这不是完整的解决方案,因为它不会在选择第一个之前对 OBJVERS 进行排序。但是如果你能解决选择合适的OBJVERS的问题,那么我认为剩下的就交给我了。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
    <MYOBJ>
        <xsl:for-each select="/DOC/AAA/OBJ/OBJVERS[position()==1]">
            <ELEM><xsl:copy-of select="*"/></ELEM>
        </xsl:for-each>
        <IMAGE><xsl:copy-of select="/DOC/DDD/FILE/*" /></IMAGE>
    </MYOBJ>
</xsl:template>

【讨论】:

  • XPath 中没有“==”运算符。即使在编译阶段,任何兼容的 XSLT 处理器都会引发错误。这个答案根本解决不了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 2020-12-27
  • 1970-01-01
  • 2012-02-16
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多