代码之家  ›  专栏  ›  技术社区  ›  Gnudiff

用XSL过滤大部分XML?

  •  0
  • Gnudiff  · 技术社区  · 15 年前

    我需要将许多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处理器不要处理任何其他事情,例如,我一直从中获取输出。

    更新:基本上,我同时解决了这个问题。我会发表我自己的答案并结束这个问题。

    最新消息2:好的,安德鲁的回答也有效,所以我只是接受它。:)

    2 回复  |  直到 14 年前
        1
  •  2
  •   Dimitre Novatchev    15 年前

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

    也就是说,下面的转换 :

    <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>
    
        2
  •  0
  •   Andrew Arnott    15 年前

    这不是完整的解决方案,因为在选择第一个对象之前,它不会对对象进行排序。但是如果你能解决选择正确对象的问题,那么我认为这将解决剩下的问题。

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