I think the most easy approach is using \DTLgetvalueforkey
(and evaluating/calling the macro defined by \DTLgetvalueforkey
):
\documentclass{article}
\usepackage{datatool}
\begin{filecontents*}{abbreviationss.csv}
"term", "abbreviation"
Machine Learning, ML
Artificial Neural Network, ANN
\end{filecontents*}
\DTLloaddb{abbreviations}{abbreviationss.csv}
\newcommand{\getabbreviation}[1]{%
#1 : %
\DTLgetvalueforkey{\scratchmacro}{abbreviation}{abbreviations}{term}{#1}%
\scratchmacro
%\scratchmacro will be \@dtlnovalue -> "Undefined Value" if #1 is not found.
% Alternatively:
% \DTLifnull{\scratchmacro}{Hey, this is undefined!}{\scratchmacro}%
}%
\begin{document}
\begin{itemize}
\item\getabbreviation{x}
\item\getabbreviation{Machine Learning}
\item\getabbreviation{x}
\item\getabbreviation{Artificial Neural Network}
\item\getabbreviation{x}
\end{itemize}
\end{document}

Like the approach of Simon Dispa this is based on \DTLforeach*
:
\documentclass{article}
\usepackage{datatool}
\begin{filecontents*}{abbreviationss.csv}
"term", "abbreviation"
Machine Learning, ML
Artificial Neural Network, ANN
\end{filecontents*}
\DTLloaddb{abbreviations}{abbreviationss.csv}
\newif\ifnotfound
\global\notfoundtrue
\newcommand{\getabbreviation}[1]{%
#1 : %
\global\notfoundtrue
\DTLforeach*[{\equal{\term}{#1}}]{abbreviations}{\abbreviation=abbreviation, \term=term}%
{\abbreviation\global\notfoundfalse\dtlbreak}%
\ifnotfound Undefined Value\fi
}%
\begin{document}
\begin{itemize}
\item\getabbreviation{x}
\item\getabbreviation{Machine Learning}
\item\getabbreviation{x}
\item\getabbreviation{Artificial Neural Network}
\item\getabbreviation{x}
\end{itemize}
\end{document}

If the real-life-scenario is not just about some itemize
-thing but you really need to catch the situation of \DTLfetch
not finding the ⟨column1 value⟩
:
With your MWE you get a lot of ! Package datatool Error: No row found in database `abbreviations' for column ` 1' matching `x'.
-errors on the terminal and in the .log-file.
Syntax of \DTLfetch
is:
\DTLfetch{⟨db name⟩}%
{⟨column1 name⟩}%
{⟨column1 value⟩}%
{⟨column2 name⟩}%
Section "6.11.1 Operating on Current Row" of the User Manual for datatool bundle version 2.32 says:
\dtlgetrowindex{⟨row cs⟩}{⟨db name⟩}{⟨col idx⟩}{⟨value⟩}
Similar to \DTLgetrowindex
but doesn't produce an error if no match is found. You can test the result by using \ifx⟨row cs⟩\dtlnovalue
.
So you can write a wrapper for \DTLfetch
which applies
\dtlgetrowindex{⟨row cs⟩}%
{⟨db name⟩}%
{⟨col idx of column1⟩}%
{⟨column1 value⟩}%
for defining ⟨row cs⟩
and then does:
\ifx⟨row cs⟩\dtlnovalue\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
⟨ tokens in case ⟨column1 name⟩ does not have a value ⟨column1 value⟩ ⟩%
}{%
\DTLfetch{⟨db name⟩}{⟨column1 name⟩}{⟨column1 value⟩}{⟨column2 name⟩}%
}%
You need the index of column1/of ⟨col idx of column1⟩
.
You can get that via \dtlcolumnindex{⟨db name⟩}{⟨column1 name⟩}
In order to have the arguments of \dtlgetrowindex
—especially ⟨col idx of column1⟩
=\dtlcolumnindex{⟨db name⟩}{⟨column1 name⟩}
—expanded before carrying out \dtlgetrowindex
, you can define a scratch-macro via \protected@edef
where expansion of the command \dtlgetrowindex
and expansion of the to-be-defined command ⟨row cs⟩
is prevented by prepending \noexpand
, but the expansion of other arguments of \dtlgetrowindex
is not prevented, and then call that scratch-macro:
\documentclass{article}
\usepackage{datatool}
%\DTLfetchifcolOneValueExists{<db name>}%
% {<column1 name>}%
% {<column1 value>}%
% {<column2 name>}%
% {<tokens in case <column1-value> does not exist>}%
%
% Turn @ into a normal letter so that it can be used as part of the name of a control sequence:
\makeatletter
% Test if the command \NewDocumentCommand is not available.
% If so, use traditional \newcommand. Otherwise use it.
\@ifundefined{NewDocumentCommand}%
{\newcommand\DTLfetchifcolOneValueExists[5]}%
{\NewDocumentCommand\DTLfetchifcolOneValueExists{mmmmm}}%
{%
% open a local scope:
\begingroup
% define the scratch macro
\protected@edef\@dtl@dogetrowforvalue{%
\endgroup\noexpand\dtlgetrowindex{\noexpand\dtl@rowidx}{#1}{\dtlcolumnindex{#1}{#2}}{#3}%
}%
% Call the scratch-macro:
\@dtl@dogetrowforvalue
% Expansion of the scratch-macro yields:
% \endgroup %<-after processing \endgroup the local scope is closed and thus the scratch-macro is undefined.
% \dtlgetrowindex{\dtl@rowidx}{<expansion of #1>}{<expansion of \dtlcolumnindex{#1}{#2}>}{<expansion of #3>}%
% % After processing \dtlgetrowindex the macro \dtl@rowidx is defined.
\ifx\dtl@rowidx\dtlnovalue\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{#5}{\DTLfetch{#1}{#2}{#3}{#4}}%
}%
\makeatother
% csv file 1
\begin{filecontents*}{abbreviationss.csv}
term, abbreviation
Machine Learning, ML
Artificial Neural Network, ANN
\end{filecontents*}
\DTLloaddb{abbreviations}{abbreviationss.csv}
\begin{document}
\begin{itemize}
\item x :
\DTLfetchifcolOneValueExists{abbreviations}%
{term}%
{x}%
{abbreviation}%
{Column `term' doesn't have a value `x'}
\item Machine Learning :
\DTLfetchifcolOneValueExists{abbreviations}%
{term}%
{Machine Learning}%
{abbreviation}%
{Column `term' doesn't have a value `Machine Learning'}
\item x :
\DTLfetchifcolOneValueExists{abbreviations}%
{term}%
{x}%
{abbreviation}%
{\DTLstringnull}
\item Artificial Neural Network :
\DTLfetchifcolOneValueExists{abbreviations}%
{term}%
{Artificial Neural Network}%
{abbreviation}%
{Column `term' doesn't have a value `Artificial Neural Network'}
\item x :
\DTLfetchifcolOneValueExists{abbreviations}%
{term}%
{x}%
{abbreviation}%
{\dtlnovalue}
\end{itemize}
\end{document}

If you wish to obtain some null-value instead of the phrase "Column `term' doesn't have a value `x' ", you can provide one of the tokens \DTLstringnull
/\DTLnumbernull
/\dtlnovalue
instead. (\DTLstringnull
yields NULL
. \DTLnumbernull
yields 0
. \dtlnovalue
yields Undefined Value
. All three tokens can be used as first argument of \DTLifnull
etc.)