【问题标题】:How to use XPath to select Cartesian Product set of non null sibling nodes?如何使用 XPath 选择笛卡尔积非空兄弟节点集?
【发布时间】:2014-01-08 08:18:12
【问题描述】:

第一次在这里发帖,所以如果我做错了什么,请不要犹豫,让我知道。

我正在使用 Altova Stylevision 打印表单文档,并且我需要为每个唯一的两个节点集合集打印一份表单副本。下面是一个示例 XML,可以更好地解释我的要求。

<form>
    <Animals>
        <Animal>
            <AName>Boomer</AName>
            <AAddress>House</AAddress>
        </Animal>
        <Animal>
            <AName>Growl</AName>
            <AAddress>Street</AAddress>
        </Animal>
        <Animal>
            <AName>Incognito</AName>
            <AAddress>Nowhere</AAddress>
        </Animal>
    </Animals>
    <People>
        <Person>
            <PName>Willy</PName>
            <PAddress>123 Common Lane</PAddress>
        </Person>
        <Person>
            <PName>Wonka</PName>
            <PAddress>Chocolate Factory</PAddress>
        </Person>
    </People>
</form>

我想从上面的示例中生成 6 个唯一值(笛卡尔积),其中包含 &lt;Animal&gt;&lt;Person&gt; 的每个组合,其中两者都不为空。因此,此示例的输出将类似于(仅显示分组,需要所有子节点而不仅仅是名称):

([Boomer, Willy], [Boomer, Wonka], [Growl, Willy], [Growl, Wonka], [Incognito, Willy], [Incognito, Wonka])

编辑:我正在尝试获取节点,而不仅仅是 &lt;Name&gt; 元素值。因为我在这个模板中包装了整个 StyleVision 表单,所以范围应该在 &lt;Animal&gt;&lt;Person&gt; 级别。这样,在表单中我可以只说 /AName, /PName, 并在表单的每个副本上为 /AName/PName 获取一个值。它应该充当元素节点的 6 个实例,每个实例代表 &lt;Person&gt;&lt;Animal&gt; 的唯一组合。

我查看了for # in # return 语法,但不知道如何返回唯一集。以下是我迄今为止尝试过的:

for $a in form/Animals/Animal, $p in form/People/Person return ($a, $p)

form/Animals/Animal | form/People/Person

谁能指出我正确的方向?

谢谢!

【问题讨论】:

    标签: xml xpath xpath-2.0 altova


    【解决方案1】:

    更新

    你的for表达式是正确的,你只需要添加一个元素构造函数就可以得到你需要的结果:

    for $animal in $x/Animals/Animal,
        $person in $x/People/Person
    return element union { $animal, $person }
    

    元素名称(示例中为union)可以是您想要的任何名称。


    这些原始代码示例将根据问题生成结果字符串。

    这有点难读,但这会做你想做的事:

    concat("(",
      concat(string-join(
        for $animal in /form/Animals/Animal/Name,
            $person in /form/People/Person/Name
        return concat("[", concat(string-join(($animal, $person), ", "), "]")), ", "), ")"))
    

    如果您可以使用 XPath/XQuery 3.0 处理器,则可以使用 || 连接运算符而不是 concat 函数调用,这(在某种程度上)更具可读性:

    "(" ||
      string-join(
        for $animal in /form/Animals/Animal/Name,
            $person in /form/People/Person/Name
        return "[" || string-join(($animal, $person), ", ") || "]"
        , ", ")
    || ")"
    

    【讨论】:

    • 感谢您的回答。我现在意识到我的问题格式不正确,我并没有真正指定我在寻找什么。我想获取整个节点,而不仅仅是字符串值。我只记得它叫笛卡尔积,我希望节点的积代表一个整体产品集。
    • 你想要现有的 Animal 和 Person 元素在一个序列中,还是想要一个 Animal 和 Person 的每个并集在一个新元素中?
    • 后者,Animal 和 Person 的每个联合都在一个新元素中。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多