使用XSL过滤大部分XML?

时间:2009-04-10 15:11:06

标签: xml xslt

我需要将许多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:好的,安德鲁的答案也有效,所以我只是接受了。 :)

2 个答案:

答案 0 :(得分:2)

这个问题的制定非常松散,这对提供更有意义的解决方案没有帮助

这就是说,下面的转型

<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>

答案 1 :(得分:0)

这不是完整的解决方案,因为在选择第一个之前它不会对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>