2012-03-11 112 views
0

我正在处理一个xml,它用它的块和单词表示一个句子。问题是,在XML中,我给出的单词顺序是根据其父块设置的,而不是它在句子中的顺序。这是XML的样子:使用xslt设置xml节点顺序

<SENTENCE> 
    <CHUNK ord="4"> 
    <CHUNK ord="2"> 
     <CHUNK ord="1"> 
     <WORD ord="0" /> 
     </CHUNK> 
     <WORD ord="2" /> 
     <CHUNK ord="3"> 
     <WORD ord="0" />> 
     </CHUNK> 
    </CHUNK> 
    <WORD ord="1" /> 
     <WORD ord="0" /> 
    <CHUNK ord="5"> 
     <WORD ord="0"> 
     <WORD ord="1" /> 
     </WORD> 
     <CHUNK ord="6"> 
     <WORD ord="0"> 
      <WORD ord="2"> 
      <WORD ord="3" /> 
      <WORD ord="1" /> 
      </WORD> 
     </WORD> 
     </CHUNK> 
    </CHUNK> 
    <CHUNK ord="7"> 
     <WORD ord="0"> 
     <WORD ord="1" /> 
     </WORD> 
    </CHUNK> 
    <CHUNK ord="8"> 
     <WORD ord="0" /> 
    </CHUNK> 
    </CHUNK> 
</SENTENCE> 

我需要知道在句子中词的实际,以使其他一些处理,但不失XML的结构。例如,在上面的例子中,输出XML应该是这样的:通过使用XSLT来创建的每一个字元素的新属性,它会显示

<SENTENCE> 
    <CHUNK ord="4"> 
    <CHUNK ord="2"> 
     <CHUNK ord="1"> 
     <WORD ord="0" senOrd="0" /> 
     </CHUNK> 
     <WORD ord="2" senOrd="1" /> 
     <CHUNK ord="3"> 
     <WORD ord="0" senOrd="3" />> 
     </CHUNK> 
    </CHUNK> 
    <WORD ord="1" senOrd="4" /> 
    <WORD ord="0" senOrd="5" /> 
    <CHUNK ord="7"> 
     <WORD ord="0" senOrd="12"> 
     <WORD ord="1" senOrd="13" /> 
     </WORD> 
    </CHUNK> 
    <CHUNK ord="8"> 
     <WORD ord="0" senOrd="14" /> 
    </CHUNK> 
    </CHUNK> 
    <CHUNK ord="5"> 
    <WORD ord="0" senOrd="6"> 
     <WORD ord="1" senOrd="7" /> 
    </WORD> 
    <CHUNK ord="6"> 
     <WORD ord="0" senOrd="8"> 
     <WORD ord="2" senOrd="10"> 
      <WORD ord="3" senOrd="11" /> 
      <WORD ord="1" senOrd="9" /> 
     </WORD> 
     </WORD> 
    </CHUNK> 
    </CHUNK> 
</SENTENCE> 

我一直在努力做的在句子中的顺序,但我甚至不知道从哪里开始。如果有人能帮助我,我将不胜感激。

这里给出的英语句子可能的XML“这仅仅是XML的例子”:

<SENTENCE> 
<CHUNK ord="1"> 
    <CHUNK ord="0"> 
     <WORD ord="1" form="is"> 
      <WORD ord="0" form="this" /> 
     </WORD> 
    </CHUNK> 
    <WORD ord="1" form="just"> 
    <CHUNK ord="2"> 
     <WORD ord="2" form="of"> 
      <WORD ord="0" form="an" /> 
     </WORD> 
     <WORD ord="1" form="example" /> 
     <CHUNK ord="0"> 
      <WORD ord="1" form="xml" /> 
      <WORD ord="0" form="the" /> 
     </CHUNK> 
    </CHUNK> 
    </CHUNK> 
</CHUNK> 

什么是senOrd属性将表明是每个单词在句子的顺序。

+0

所以说,如果你用大块的ord命令在一个句子中的单词,然后在这个单词的ord中,你会在句子中排序吗?如果是这样,那么我想你需要创建一个xpath,按照该顺序选择数据,然后使用计数器添加senOrd。计数器可能必须是递归模板的参数,每次调用都会递增(因为xslt是有效的)。但这是我能记住xslt的限制[编辑:哦,但是你需要保存顺序,所以首先添加一个属性来记录,然后重写/删除] – 2012-03-11 19:43:27

+0

我不明白你的描述,我可以注意在你的输出中senOrd总是ord + ord-of-parent是你需要实现的规则吗? – 2012-03-11 19:47:11

+0

也许这个例子xml我的帖子不是很复杂。但是真正的xml要复杂得多,因为有更多的嵌套块和单词(这些xml文件在语法分析之后代表句子,所以根据输入句子输出会更容易或不更简单)。 – Ion 2012-03-11 20:22:34

回答

0

我想你需要计算所有字属于元素与低阶自己元素,加上所有元素与较低的ord属性在相同的块。

<xsl:value-of select="count(//WORD[ancestor::CHUNK[1]/@ord &lt; $currentOrd]) 
    + count(//WORD[ancestor::CHUNK[1]/@ord = $currentOrd][@ord &lt; current()/@ord])"/> 

currentOrd定义如下:考虑到下面的XSLT

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

    <xsl:template match="WORD"> 
     <xsl:variable name="currentOrd" select="ancestor::CHUNK[1]/@ord"/> 
     <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="senOrd"> 
      <xsl:value-of select="count(//WORD[ancestor::CHUNK[1]/@ord &lt; $currentOrd]) + count(//WORD[ancestor::CHUNK[1]/@ord = $currentOrd][@ord &lt; current()/@ord])"/> 
     </xsl:attribute> 
     <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

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

当应用于以下示例XML,

<xsl:variable name="currentOrd" select="ancestor::CHUNK[1]/@ord"/> 

所以输出

<SENTENCE> 
    <CHUNK ord="4"> 
     <CHUNK ord="2"> 
     <CHUNK ord="1"> 
      <WORD ord="0" senOrd="0"/> 
     </CHUNK> 
     <WORD ord="2" senOrd="1"/> 
     <CHUNK ord="3"> 
      <WORD ord="0" senOrd="2"/> 
     </CHUNK> 
     </CHUNK> 
     <WORD ord="1" senOrd="4"/> 
     <WORD ord="0" senOrd="3"/> 
     <CHUNK ord="5"> 
     <WORD ord="0" senOrd="5"> 
      <WORD ord="1" senOrd="6"/> 
     </WORD> 
     <CHUNK ord="6"> 
      <WORD ord="0" senOrd="7"> 
       <WORD ord="2" senOrd="9"> 
        <WORD ord="3" senOrd="10"/> 
        <WORD ord="1" senOrd="8"/> 
       </WORD> 
      </WORD> 
     </CHUNK> 
     </CHUNK> 
     <CHUNK ord="7"> 
     <WORD ord="0" senOrd="11"> 
      <WORD ord="1" senOrd="12"/> 
     </WORD> 
     </CHUNK> 
     <CHUNK ord="8"> 
     <WORD ord="0" senOrd="13"/> 
     </CHUNK> 
    </CHUNK> 
</SENTENCE> 
+0

谢谢蒂姆。我一直在用我的一些xml文件证明你的xslt,它的作用就像魅力(现在我看到你的回复并不那么复杂)。感谢大卫和安德鲁的帮助,我很抱歉,如果我把我的不好的解释弄糊涂了(我的英文不够好)。 – Ion 2012-03-11 22:17:10

0

我不知道,如果你的问题描述,但是这会产生所要求的输出

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 


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

<xsl:template match="word/@ord"> 
<xsl:copy-of select="."/> 
<xsl:attribute name="senOrd"> 
    <xsl:value-of select=". + ancestor::chunk[1]/@ord"/> 
</xsl:attribute> 
</xsl:template> 

</xsl:stylesheet> 
+0

它与第一个例子一起工作,但是我刚刚发布的那个没有。 – Ion 2012-03-11 20:31:07

+0

我很抱歉,我无法理解你的问题描述,所以只是在这个例子中引起了轰动。如果你编辑你的问题来描述如何计算你想在semOrd中输入的数字,那么我或其他人肯定会发布答案。这个问题(至少对我来说)与xslt无关,我只是不知道xslt应该编码的总和。 – 2012-03-11 21:09:31

+0

我想我的评论描述了需要什么。大块是有序的。然后,在大块内,这些词是有序的。需要的是顺序排列后的顺序索引。当然,在第二个例子中,大块排序从1开始,或者某些senOrd值丢失或者从未困扰过来回复我是没有帮助的。但如果你看例子,它们与我的建议是一致的。 – 2012-03-11 21:28:04