简体   繁体   English

xpath表达式强制返回不存在的节点

[英]xpath expression to force to return absent nodes

<matrix id="2x2withNulls">
    <row>
        <column num="1">346</column>
    </row>
    <row>
        <column num="1">444</column>
        <column num="2">56</column>
    </row>
</matrix>

I need to iterate over the whole matrix, is there any way to force the expression to create a node where null? 我需要遍历整个矩阵,是否有任何方法可以强制表达式在null处创建节点?

Ideally /matrix/row/column someway returns the four expected nodes. 理想情况下, /matrix/row/column某种方式返回四个预期节点。

/matrix/row/column[as many as max(foreach /matrix/column/)] , duplicate if necessary or /matrix/row/column[not(exists num where exists in other colum)-> create it] /matrix/row/column[as many as max(foreach /matrix/column/)] ,如有必要则复制,或/matrix/row/column[not(exists num where exists in other colum)-> create it]

I can only use one expression, as the expression is a parameter for a third party application. 我只能使用一个表达式,因为该表达式是第三方应用程序的参数。

Perhaps there must a way to force to result column num1 repeated for the first row, so it always returns max(columns) even if they are duplicates of the last existintg column in the half empty row. 也许必须有一种方法可以强制导致第一行重复num1列,因此即使它们是半空行中最后一个existintg列的重复,它也始终会返回max(columns)。

The concept of "selecting an absent node" is an interesting one, but is likely to lead you down a false trail. “选择一个不存在的节点”的概念很有趣,但很可能会导致您走错路。 As some philosopher once said of God, existence is not a predicate; 正如一些哲学家曾经提到的上帝,存在不是谓词。 you can't select all the nodes that don't exist. 您不能选择所有不存在的节点。

The tricky bit is your statement "I can only use one expression, as the expression is a parameter for a third party application." 棘手的是您的陈述“我只能使用一个表达式,因为该表达式是第三方应用程序的参数”。 That seems to rule out XSLT, although you've included the XSLT tag in your question. 尽管您已在问题中包括XSLT标记,但这似乎排除了XSLT。 So I think it would be good to know the constraints more precisely. 因此,我认为最好更精确地了解约束条件。

I would tweak Erat's solution a little: 我会稍微调整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>

If you are creating the xml yourself, you could start out by making sure it validates against an xsd that has a sequence with minOccurs and maxOccurs set to a desired count; 如果您是自己创建xml ,则可以先确保它针对xsd进行验证,该xsdsequenceminOccursmaxOccurs设置为所需的计数。 that would do the trick in constraining the number of nodes per se. 这样就可以有效地限制节点本身的数量。

Read up on xsd sequence here . 这里阅读xsd sequence

If you're getting this xml out of the 3rd-party app, but want to include empty nodes, you can use LinqToXml (assuming you can use C# in your project and also assuming xDoc is an XDocument containing the xml ): 如果您LinqToXml第三方应用程序中获取此xml,但要包含空节点,则可以使用LinqToXml (假设您可以在项目中使用C#,并且还假设xDoc是包含xmlXDocument ):

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);
        }
    }
}

Note that I did not test this, but even if it doesn't completely work, you get the general gist of it. 请注意,我没有对此进行测试,但是即使它不能完全正常工作,您也可以大致了解它。

You will have to reconstruct the result, and create new columns when necessary. 您将必须重建结果,并在必要时创建新列。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM