1
$\begingroup$

I want filter information from a .xml file, from elements that look like this:

XMLElement["div", {"class" -> "art_title linkable"},
  {XMLElement["a", {"shape" -> "rect", "class" -> "ref nowrap", "href" -> "XXXX"},
    {"name"} ]}]

I use the following code to filter out the text from the a element:

Cases[data, 
 XMLElement[
    "div", {"class" -> "art_title linkable"}, {XMLElement[
      "a", {___}, {papername_}]}] :> {papername}, {0, Infinity}];

(* {{"name"}} *)

But this does not work if the content of the a element is more complicated:

XMLElement["div", {"class" -> "art_title linkable"},
  {XMLElement["a", {"shape" -> "rect", "class" -> "ref nowrap", "href" -> "XXXX"},
    {XMLElement["b", {}, {"namepart1"}], "namepart2"} ]}]

... which gives the result {}.

How can I extract just the text "namepart1namepart2 in this second case?

$\endgroup$
2
  • $\begingroup$ What do you mean "special conditions"? If you just want to handle other XML tags use Alternatives, e.g. XMLElement["a"|"b", _, {papername_}] $\endgroup$
    – b3m2a1
    Commented Nov 18, 2017 at 3:00
  • $\begingroup$ I reworded the question, hopefully for clarity. If you disagree, please revert the change. $\endgroup$
    – WReach
    Commented Nov 18, 2017 at 4:18

1 Answer 1

1
$\begingroup$

We can define a helper function that extracts the text from inner elements:

innerText[list_List] := StringJoin[innerText /@ list]
innerText[XMLElement[_, _, elements_]] := innerText[elements]
innerText[s_String] := s
innerText[_] := ""

Then, given:

data = ImportString[#, "XML"]& @
"<html><body>
  <div class='art_title linkable'>
    <a shape='rect' class='ref nowrap' href='XXXX'>name</a>
  </div>
  <div class='art_title linkable'>
    <a shape='rect' class='ref nowrap' href='XXXX'><b>namepart1</b>namepart2</a>
  </div>
</body></html>"

... we can use innerText within Cases to obtain:

Cases[data
, XMLElement["div", {"class" -> "art_title linkable"}, {XMLElement["a", _, children_]}]
    :> innerText[children]
, {0, Infinity}
]

(* {"name", "namepart1namepart2"} *)
$\endgroup$
1
  • $\begingroup$ Thank you, your method is well, it helpful. $\endgroup$
    – zongxian
    Commented Nov 18, 2017 at 4:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.