2015-11-17 28 views
0

我有一个XML <row>元素的数组,每个元素可以有一个<query>元素的数组。它看起来是这样的:XSLT:如何检查孩子的平等

<row><query></query><query></query></row> 
<row><query></query><query></query></row> 
<row><query></query><query></query></row> 
<row><query></query><query></query></row> 

我要打印表格中的情况下query孩子是跨row元素,如果query孩子们在所有row孩子一样逗号分隔字符串不同。

我撰写这一个<xsl:when>

<xsl:choose> 
    <xsl:when test="[Table condition]"> 
    <!--code to print table--> 
    </xsl:when> 
    <xsl:otherwise> 
    <!--code to print string--> 
    </xsl:otherwise> 
</xsl:choose> 

应该是什么Table Condition

我正在使用XSLT v 1.0。我知道有一种叫做deep equals的东西,但不明白如何在这里使用它。

你能帮我吗?

+0

对不起,不明白你需要什么......请提供样例数据(在你的空XML结构中)和预期的输出。 – Shnugo

+0

你只是想比较一下子元素的数量吗?或者他们的数据呢? –

+0

@MartinHonnen我想比较他们的数据。假设所有“行”中孩子的数量总是相等,但数据可能不同。 –

回答

0

deep-equal是在XSLT/XPath 2.0中引入了一个函数,这里是使用(然后这当然需要使用XSLT 2.0处理器等撒克逊9,Altova的,XmlPrime)样品:

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

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

    <xsl:template match="table[not(row[some $sibling in ../row satisfies not(deep-equal(., $sibling))])]"> 
     <xsl:value-of select="row/query" separator=","/> 
    </xsl:template> 
</xsl:transform> 

我有显然将一个案例的条件放在match模式中,并简单地让其他表格的复制通过身份转换工作。

与样本输入像

<root> 
    <table> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
    </table> 
    <table> 
     <row><query>2</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
    </table> 
</root> 

结果是

<root> 
    1,2,1,2,1,2,1,2 
    <table> 
     <row><query>2</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
    </table> 
</root> 
+0

有没有办法在XSLT 1.0中执行此操作?我正在使用它。 –

+0

您在编写XSLT代码时是否知道'query'元素的数量? –

+0

不,我不知道。它们可能会有所不同,但是它们的数量对于所有“行”元素是相同的 –

0

如果您query元素中纯文本,它不应该是在XSLT 1.0太难了。举例来说,我认为两个rows一个样品可能是这样的:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <row><query>foo</query><query>foo</query></row> 
    <row><query>foo1</query><query>foo2</query></row> 
</root> 

如果通过XSLT模板处理这些数据像

<xsl:for-each select="//row"> 
     <xsl:choose> 
      <xsl:when test="query[not(. = preceding-sibling::query or . = following-sibling::query)]"> 
       There is at least one query element which is different from the others 
       in the same raw. 
      </xsl:when> 
      <xsl:otherwise> 
       All query elements in this row are equal. 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 

你得到预期的结果:第一row被处理为“平等”,另一为“不同”。 这是通过检查前面和后面的query来完成的:是否至少有一个不等于所有前后兄弟姐妹?

这是或多或少你在找什么?

+0

这是一个危险的比较,不是吗?如果你有' ABÇ'和'一个 BC'话虽然值是不同的比较将给予正确的。 –

+0

'query'内不一定有文字。它可能有一个或多个孩子。我们可以假设'query'的'rows's中的子节点具有相同的标签,但可能不具有相同的值,这正是我想要比较的。 –

+0

@Martin Honnen,至少在撒克逊6中,它在两种情况下都会返回“false”(因为它应该)@Core_Dumped:嗯,在这种情况下,我建议的解决方案将不起作用。解决方法是将所有查询内容转换为字符串,然后进行比较。 – cis