【问题标题】:Select parent and child attribute value选择父子属性值
【发布时间】:2018-10-12 11:25:11
【问题描述】:

我有一个如下的 xml 文件:

<tag>
   <file name="name1">
      <error message="error1"/>
      <error message="error2"/>
   </file>
   <file name="name2">
      <error message="error1"/>
      <error message="error2"/>
   </file>
</tag>

希望能得到下一个结果:

name1: error1, error1;
name2: error1, error1

我正在尝试做这样的事情:

*//file/@name | //file/error/@message*

但这当然行不通。我可以实现地图吗?

【问题讨论】:

  • 您确定预期的结果吗,因为输出似乎与 HTML 片段不同,error1error2 在那里。请说得更清楚

标签: xml parsing xpath


【解决方案1】:

使用 XPath 3.1,

string-join(/tag/file ! (@name || ': ' || string-join(error/@message, ', ')), '#')

其中 # 表示根据宿主语言的约定转义的换行符,例如\n 用于 Java,&amp;#xa; 用于 XSLT。

对于 XPath 2.0,将 A!B 替换为 for $a in A return B 并将 A||B 替换为 concat(A, B)

XPath 1.0:没有宿主语言支持是不可能的。

【讨论】:

    【解决方案2】:

    这仅适用于 XPath-2.0 或更高版本。您可以使用以下表达式创建一个字符串作为结果。它使用适当的分隔符 , 和 LF&amp;#xa;

    for $nam in /tag/file/@name, $msg in $nam/../error return concat(if (generate-id($msg) = generate-id($nam/../error[1])) then concat($nam,': ',$msg/@message) else $msg/@message, if (generate-id($msg) = generate-id($nam/../error[last()])) then ';&#xa;' else ',')
    

    输出是:

    name1: error1, error2;
    name2: error1, error2;
    

    此输出与上面您想要的输出(error2 而不是error1)和结尾的; 略有不同。如果您需要删除最后一个;,您可以通过实施与换行相同的原则来实现。

    P.S.:检查第一个和最后一个元素的方法似乎不是最理想的,因此可能还有改进的余地。

    【讨论】:

    • 是的,我已经尝试改进我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多