Skip to content

How to check whether a key exists or not? #77

Closed

Description

@amalgame21

Sorry I am a begginner in latex.

Take the example.json in README.md as example.

In example.json, the key father is not exist.

How can I check if the key or its value exist or not?

I want to keep using example.json when father key does not exist,
if father key exist, I want to use another-example.json instead.

I tested something like this but not successful

\JSONParseFromFile{\myJSONdata}{example.json}
\ifx\JSONParseValue{\myJSONdata}{father}\empty
  dosomething
\else
  dosomethingelse
  \JSONParseFromFile{\myJSONdata}{another-example.json}
\fi

To be exact, I am trying to manage secrets in json with sops in a latex project.
When the json file is encrypted, it have an extra key called sops like this and it is not ready to be used.
When the json file is decrypted, that sops key disappeared, and it is ready to be used.

Sorry I did not noticed the "Discussions" exists.

Activity

  1. jasperhabicht commented on Sep 3, 2025

    @jasperhabicht
    Owner

    Hi, thank you for your enquiry! It is fine to post it here as it could be an enhancement request. Your code tests whether the value assigned to the key father exists, but not whether this key exists altogether.

    To test whether a key contains an empty value, you can test the value against \empty (similar like what you tried in your example, but you need to store the parsed value into some token variable that you then can use for comparison):

    \documentclass{article}
    \usepackage{jsonparse}
    
    \begin{document}
    
    \JSONParse{\myjson}{ { "foo" : "" , "bar" : "baz" } }
    \JSONParseValue[store in=\myvalueA]{\myjson}{foo}
    \JSONParseValue[store in=\myvalueB]{\myjson}{bar}
    
    \ifx\myvalueA\empty
        empty
    \else
        not empty
    \fi
    
    \ifx\myvalueB\empty
        empty
    \else
        not empty
    \fi
    
    \end{document}

    Since the JSON data is parsed into a property list, you can simply use \prop_if_in:NnTF to test whether a key exists in this property list, for example like this:

    \documentclass{article}
    \usepackage{jsonparse}
    
    \begin{document}
    
    \JSONParse{\myjsonA}{ { "foo" : "" , "bar" : "baz" } }
    \JSONParse{\myjsonB}{ { "foo" : "" } }
    
    \UseName{prop_if_in:NnTF}\myjsonA{bar}{key exists}{key does not exist}
    
    \UseName{prop_if_in:NnTF}\myjsonB{bar}{key exists}{key does not exist}
    
    \end{document}

    Note that you can't simply overwrite a property list but you need to \relax it first:

    \documentclass{article}
    \usepackage{jsonparse}
    
    \begin{document}
    
    \JSONParseFromFile{\myjson}{example.json}
    
    \UseName{prop_if_in:NnF}\myjson{bar}{
        \let\myjson\relax
        \JSONParseFromFile{\myjson}{example-2.json}
    }
    
    ...
    
    \end{document}

    Also, you can't use the \JSONParse command as argument to another command (for the \JSONParseFromFile command, this issue however does not apply, I only add this as a reminder). You would need to do something along the following lines:

    \documentclass{article}
    \usepackage{jsonparse}
    
    \begin{document}
    
    \newif\ifparseother
    
    \JSONParse{\myjson}{ { "foo" : "" } }
    
    \UseName{prop_if_in:NnF}\myjson{bar}
        {\parseothertrue}
    
    \ifparseother
    \let\myjson\relax
    \JSONParse{\myjson}{ { "foo" : "" , "bar" : "baz" } }
    \fi
    
    \JSONParseValue{\myjson}{bar}
    
    \end{document}

    Maybe I can add a user-level command named \JSONParseKeyExistsTF that is essentially just a wrapper around \prop_if_in:NnTF if this is required.

  2. self-assigned this
    on Sep 3, 2025
  3. amalgame21 commented on Sep 3, 2025

    @amalgame21
    Author

    Thank you! It is extremely difficult to me, I don't even know what \UseName \let \relax \prop_if_in:NnTF are, even after some googling.
    But it just works using your code!!
    Thank you so much

  4. jasperhabicht commented on Sep 3, 2025

    @jasperhabicht
    Owner

    Let me shortly answer this:

    Using \UseName, you can easily use commands defined by the LaTeX3 layer which has a lot of useful commands and also introduces to LaTeX the concept of property lists which the jsonparse package makes use of. (Because commands of the LaTeX3 layer have a special syntax, you can't use them just like this in normal code.) A property list essentially contains key-value pairs. In the context of the jsonparse package, this concept is used to store the JSON data as key-value pairs in such a property list. For example the JSON data { "foo" : "bar" } would be parsed into a property list that has exactly one entry with the key foo and the corresponding value bar.

    The command \prop_if_in:NnTF checks whether the key given as second argument exists in the property list given as first argument. If yes (true branch, T), it will execute the code given to the third argument. If not (false branch, F), it will execute the code given to the fourth argument. There exist also the commands \prop_if_in:NnT and \prop_if_in:NnF that only have a true or false branch respectively.

    The commands \relax and \let are commands that you should probably get familiar with as they will pop up often when working with TeX. Using \let, you can assign a command the meaning of another. With \let\foo\relax you essentially say that \foo shall be an exact copy of \relax and both do the same thing when expanden. Now, \relax essentially just means "do nothing". So, the above means: let \foo do nothing (and by this overwrite its possible prior assignment).

  5. Repository owner locked and limited conversation to collaborators on Sep 3, 2025
  6. converted this issue into a discussion #79 on Sep 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions