<matrix id="2x2withNulls">
<row>
<column num="1">346</column>
</row>
<row>
<column num="1">444</column>
<column num="2">56</column>
</row>
</matrix>
我需要迭代整个矩阵,有没有办法强制表达式创建一个null的节点?
理想情况下,/matrix/row/column
会返回四个预期的节点。
/matrix/row/column[as many as max(foreach /matrix/column/)]
,必要时重复
要么
/matrix/row/column[not(exists num where exists in other colum)-> create it]
我只能使用一个表达式,因为表达式是第三方应用程序的参数。
也许必须有一种方法强制为第一行重复结果列num1,所以它总是返回max(列),即使它们是半空行中最后一个existsintg列的重复。
答案 0 :(得分:4)
&#34;选择缺席节点的概念&#34;是一个有趣的,但可能会导致你走错路。正如一位哲学家曾经说过的上帝,存在不是一个谓词;你不能选择所有不存在的节点。
棘手的一点是你的陈述&#34;我只能使用一个表达式,因为表达式是第三方应用程序的参数。&#34;这似乎排除了XSLT,尽管您在问题中包含了XSLT标记。所以我认为更准确地了解约束会很好。
我会稍微调整一下Erat的解决方案:
return <matrix> {
$matrix/@*,
for $row in $matrix/row
return <row> {
for $i in 1 to 2
return ($row/column[@num=$i], <column num="{$i}"/>)[1]
} </row>
}</matrix>
答案 1 :(得分:3)
如果您自己创建xml
,则可以首先确保对xsd
sequence
minOccurs
和maxOccurs
的{{1}}进行验证。设置为所需的计数;这样做可以限制节点本身的数量。
阅读xsd
sequence
here。
如果您从第三方应用程序中获取此xml,但想要包含空节点,则可以使用LinqToXml
(假设您可以在项目中使用C#并假设xDoc
是包含XDocument
)的xml
:
public void AddEmptyNodesIf(XDocument xDoc, int targetElementCount = 4)
{
XElement e = new XElement("column");
e.Add(new XAttribute("num", null));
foreach (XElement row in xDoc.Elements("row"))
{
int lastOccurringId = int.Parse(row.Elements("column")
.Last().Attribute("num").Value);
while (row.Elements("column").Count() < targetElementCount)
{
lastOccurringId++;
e.Attribute("num").Value = lastOccurringId.ToString();
row.Add(e);
}
}
}
请注意,我没有对此进行测试,但即使它没有完全奏效,您也会得到它的一般要点。
答案 2 :(得分:2)
您必须重建结果,并在必要时创建新列。
let $matrix :=
<matrix id="2x2withNulls">
<row>
<column num="1">346</column>
</row>
<row>
<column num="1">444</column>
<column num="2">56</column>
</row>
</matrix>
return element matrix {
$matrix/@*,
for $row in $matrix/row
return element row {
for $i in 1 to 2
return
if ($row/column[@num=$i])
then $row/column[@num=$i]
else element column { attribute num { $i }}
}
}