3

I have two csv files. I want to use the first (countries.csv) to generate sections, and then filter the second (bottles.csv) by the name of the section. Below is an MWE - you can see that the nested file is read correctly, but csvsimple does not continue with the next row of the parent file (only reads "Argentina"). I also include the sample with filtering, which seems to indicate that as soon as reading the nested CSV everything else about the parent CSV is forgotten.

How to nest (loop?) through two different tables and apply filters?

Thanks!

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}

\begin{filecontents*}{countries.csv}
country
Argentina
Belgium
\end{filecontents*}

\begin{filecontents*}{bottles.csv}
bottlename, bottlecountry
Bottle A1, Argentina
Bottle B1, Belgium
Bottle A2, Argentina
Bottle C1, China
\end{filecontents*}

\begin{document}

Table of countries.csv (Parent)\\
\csvreader[head to column names]{countries.csv}{}{%
\country\\
}

Table of bottles.csv (Child)\\
\csvreader[head to column names]{bottles.csv}{}{%
\bottlename \bottlecountry\\
}

Table of bottles nested in table of countries. Parent file is not read after \emph{Argentina}\\
\csvreader[head to column names]{countries.csv}{}{%
\section{\country}
\csvreader[head to column names]{bottles.csv}{}{%
\bottlename \bottlecountry\\
}
}

Table of bottles nested in table of countries, with filtering (manually chose "Argentina")\\
\csvreader[head to column names]{countries.csv}{}{%
\section{\country}
\csvreader[filter equal={\bottlecountry}{Argentina},head to column names]{bottles.csv}{}{%
\bottlename \bottlecountry\\
}
}

Table of bottles nested in table of countries, with filtering. Does not remember the country from the parent file.\\
\csvreader[head to column names]{countries.csv}{}{%
\section{\country}
\csvreader[filter equal={\bottlecountry}{\country},head to column names]{bottles.csv}{}{%
\bottlename \bottlecountry\\
}
}

\end{document}
4

First, you cannot nest a \csvreader into another \csvreader. But, you could read the countries, remember them, and then read the bottles.

In my following suggestion, I use the list features from the etoolbox package to store the country names into a \countrylist. Next, we loop through this list using \dolistloop which itself uses the \do macro. This \do macro contains the reading of the bottles:

\documentclass{article}
\usepackage{filecontents}
\usepackage{csvsimple}
\usepackage{etoolbox}

\begin{filecontents*}{countries.csv}
country
Argentina
Belgium
\end{filecontents*}

\begin{filecontents*}{bottles.csv}
bottlename, bottlecountry
Bottle A1, Argentina
Bottle B1, Belgium
Bottle A2, Argentina
Bottle C1, China
\end{filecontents*}

\begin{document}

\csvreader[head to column names]{countries.csv}{}{%
  \listeadd{\countrylist}{\country}%
}

\renewcommand*{\do}[1]{%
  \section{#1}%
  \csvreader[filter equal={\bottlecountry}{#1},head to column names]{bottles.csv}{}{%
    \bottlename\ (from \bottlecountry)\\
  }%
}
\dolistloop{\countrylist}

\end{document}

enter image description here

  • Thank you Thomas! The example works nicely, just what I need! But it gives an error When I use it with my own list when it exceeds ~40 lines in my bottles.csv. ("Tex capacity exceeded, sorry [save size = 50000]. I'll try to increase the memory tomorrow, can't seem to find it now. – Kutscher Jan 5 '15 at 23:24
  • 1
    @Kutscher I just extended the example with 500 dummy bottles in bottles.csv and I got no such error. Maybe, something else in your real example causes this (?). – Thomas F. Sturm Jan 6 '15 at 7:36
  • 1
    After moving a \centering{} that was containing the \section and \csvreader into the \csvreader it is working! Thank you again Thomas! – Kutscher Jan 6 '15 at 23:46

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.