我正在尝试模式匹配运行mochixpath返回的这些值。模式显然是[elemName,htmlAttrs,children],但我真正需要的是以下值:UserNameA和"这是一条消息"
[{"tr", [{"bgcolor", "White"}],
[{"td", [{"class", "Topic"}],
[{"div", [],
[{"a", [{"class", "lnkUserName"}, {"href", "/users/prof.aspx?u=27149"}],
["UserNameA"]
}]
}]},
{"img", [{"alt", ""}, {"src", "/Images/Icons/userIcon.gif"}], []},
{"td", [{"class", "bHeader"}],
[{"div", [{"style", "float:left;width:77%;"}],[
{"a", [{"class", "PostDisplay"}],
["This is a message"]}]
}]
}]
基本上我使用xpath输出中的解析xml来获取用户名和他们发送的消息。我对elixir和模式匹配的概念很新,所以非常感谢任何帮助。
答案 0 :(得分:0)
输出有问题,因为当我将它复制到控制台时会出现语法错误,所以我假设你有tr,td,img和其他td。
模式匹配可用于以这种方式展开。假设您将整个数据放在变量Data
中,您可以使用以下内容提取内容:
[TR] = Data,
{_Name, _Attrs, Contents} = TR.
现在内容又是一个节点列表:[Td1, Img, Td2]
,所以你可以这样做:
[Td1, Img, Td2] = Contents.
依此类推,直到你真正达到你的内容。但是编写这个非常繁琐,你可以使用递归代替。让我们定义contents
函数,递归扫描元素。
contents({_Name, _Attrs, Contents}) ->
case Contents of
[] -> []; % no contents like in img tag
[H | T] ->
case is_tuple(H) of
% tupe means list of children
true -> lists:map(fun contents/1, [H | T]);
% otherwise this must be a string
_ -> [H | T]
end
end.
这将返回嵌套列表,但您可以在最后运行lists:flatten
,如下所示:
Values = lists:flatten(contents(Data)).
答案 1 :(得分:0)
在您的示例中,卷曲和方括号不平衡。我想最后错过了}]
。
似乎表达式的深度可能会有所不同,因此您必须递归地探索它。下面的代码是这样做的,假设你会在类型" a"中找到信息。元素:
-module (ext).
-compile([export_all]).
extL(L) -> extL(L,[]).
extL([],R) -> R;
extL([H|Q],R) -> extL(Q, extT(H) ++ R).
extT({"a",PropL,L}) ->
case proplists:get_value("class",PropL) of
"lnkUserName" -> [{user_name, hd(L)}];
"PostDisplay" -> [{post_display,hd(L)}];
_ -> extL(L,[])
end;
extT({_,_,L}) -> extL(L,[]).
使用您的示例返回proplist [{post_display,"This is a message"},{user_name,"UserNameA"}]