1
$\begingroup$

I have a complicated file here as a text file which contains numbers and letters. There is a number with value -13.997315618223263 at line 13:

      <SCALAR_AVERAGE name="Eng"><MEAN>-13.997315618223263</MEAN></SCALAR_AVERAGE>

I cannot import the file as table. Is there any way to import the file and extract this value? It seems that if I copy and past is easier way but I have a lot of files every which includes a number (albeit different values). I wish to prevent opening each file individually and copying the value.

$\endgroup$
2
  • 2
    $\begingroup$ That looks like XML. There's an XML parser inside Mathematica. $\endgroup$ – b3m2a1 Apr 8 '20 at 9:50
  • $\begingroup$ The file has xml format. I thought it is difficult to import, then I changed it to a dat file. I did not know there is a way to import xml files $\endgroup$ – Inzo Babaria Apr 8 '20 at 13:39
3
$\begingroup$

The problem with importing as XML is that the file is not a complete XML document, it is missing an outer enclosing tag. One way to get around that is to add a tag, import as XML, and extract the value of the MEAN element:

testString = Import["~/Downloads/test.dat", "Text"];
testXML = ImportString["<test>" <> testString <> "</test>", "XML"];
Cases[testXML, XMLElement["MEAN", __], Infinity] // Map[Last] // ToExpression

(* {{-13.9973}, {-13.8796}} *)
$\endgroup$
1
  • $\begingroup$ You are very intelligent!!! $\endgroup$ – Inzo Babaria Apr 9 '20 at 7:28
1
$\begingroup$

The imported data usually is an array of strings. Thus, you should parse the strings to take the numbers. The principle of parsing depend on the your understanding of the structure of file content. This is usual way for any text-processing.

Looking onto your string, I supposed that desired numbers sit between tags Mean. So, just search for position of them in the string and take the substring from the between.

str = "<SCALAR_AVERAGE \
name=\"Eng\"><MEAN>-13.997315618223263</MEAN></SCALAR_AVERAGE>";

number=ToExpression@StringTake[str,
  {Last@First@StringPosition[str, "<MEAN>"] + 1, 
   First@First@StringPosition[str, "</MEAN>"] - 1}]
$\endgroup$
4
  • $\begingroup$ This line is in the body of a file. Do you mean I should copy "<SCALAR_AVERAGE \ name=\"Eng\"><MEAN> A Value</MEAN></SCALAR_AVERAGE>" for each file? $\endgroup$ – Inzo Babaria Apr 8 '20 at 13:41
  • $\begingroup$ @InzoBabaria, I guess, you can do easy data=Import[...] without additional help from my side. Each data[[i]] will be equivalent to the str $\endgroup$ – Rom38 Apr 8 '20 at 14:08
  • $\begingroup$ Thank you so much. I extracted it by str = data[[13]]. It likes as {"<SCALAR_AVERAGE", \ "name=\"Eng\"><MEAN>-13.997315618223263</MEAN></SCALAR_AVERAGE>"}. It means that we have additional {....}. So sorry for my question: How can we remove { } to reach the internal expression i.e., "<SCALAR_AVERAGE \ name=\"Eng\"><MEAN>-13.997315618223263</MEAN></SCALAR_AVERAGE>" $\endgroup$ – Inzo Babaria Apr 8 '20 at 14:28
  • $\begingroup$ @InzoBabaria, In your case the data is a list of lists. Therefore, you should use an additional index when take the string: str=data[[i,1]]; This 1 will "remove" one level of brackets {..} Or alternatively you can use str=First@data[[i]]; $\endgroup$ – Rom38 Apr 8 '20 at 15:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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