Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Using ? and ?? in XSLT patterns #1776

Open
michaelhkay opened this issue Feb 6, 2025 · 5 comments · May be fixed by #1782
Open

Using ? and ?? in XSLT patterns #1776

michaelhkay opened this issue Feb 6, 2025 · 5 comments · May be fixed by #1782
Labels
Feature A change that introduces a new feature PR Pending A PR has been raised to resolve this issue XSLT An issue related to XSLT

Comments

@michaelhkay
Copy link
Contributor

I propose that the pattern P1 ? P2, where P1 and P2 are patterns, should match any labelled item $L provided that $L matches P2, and $L?.. (that is, ($L => label())?parent ) matches P1.

Similarly, the pattern P1 ?? P2, where P1 and P2 are patterns, should match any labelled item $L provided that $L matches P2, and $L?... (that is, ($L => label())?ancestors() ) matches P1.

Note that neither the syntax nor the semantics are directly related to the lookup operator in XPath. In particular, P2 is a pattern, not a KeySpecifier. But there is a strong analogy, both with the use of ? and ?? in XPath expressions, and with the use of / and // in patterns.

@michaelhkay michaelhkay added XSLT An issue related to XSLT Feature A change that introduces a new feature labels Feb 6, 2025
@Arithmeticus
Copy link
Contributor

An example or two to illustrate the utility?

@michaelhkay
Copy link
Contributor Author

michaelhkay commented Feb 7, 2025

An example or two

I've deliberately split the whole subject of recursive-descent transformation of JSON structures into a number of small pieces that can be defined and explained independently, but I think the utility only really becomes apparent when you put them together into worked use cases. I will try to do that synthesis in the form of proposed examples in the spec.

A lot of it is driven by "filling the gaps" - these are things we are accustomed to doing when processing XML, which prove difficult to do when processing JSON. Matching things by their "container" context is probably even more important in JSON than in XML, because the things in question don't have names in the way that XML elements do.

@michaelhkay
Copy link
Contributor Author

For example, given the JSON:

{
  "event": {
    "name": "Bond Movies",
    "movies": [
      {
        "name": "Licence to Kill",
        "star": "Timothy Dalton",
        "rating": 6.6
      },
      {
        "name": "GoldenEye",
        "star": "Pierce Brosnan",
        "rating": 7.2
      },
      {
        "name": "Tomorrow Never Dies",
        "star": "Pierce Brosnan",
        "rating": 6.5
      },
      {
        "name": "Skyfall",
        "star": "Daniel Craig",
        "rating": 7.8
      }
    ]
  }
}

we might want to match individual movies with a pattern such as

match=".[?name="Bond Movies"] ?? ~record(name, star, rating, *) [?rating > 5]"

@michaelhkay
Copy link
Contributor Author

Supersedes issue #1026 (effectively a duplicate)

@michaelhkay michaelhkay linked a pull request Feb 7, 2025 that will close this issue
@michaelhkay michaelhkay added the PR Pending A PR has been raised to resolve this issue label Feb 7, 2025
@michaelhkay
Copy link
Contributor Author

michaelhkay commented Feb 8, 2025

Working this through, I think this proposal is valuable, but it's not the whole answer. Looking at actual JSON from a live application, I see stuff like this nested about 5 levels deep within the JSON document:

               "selectedOptions": [
                  {
                     "name": "Language options",
                     "value": "",
                     "valuesArray": [],
                     "selections": [],
                     "type": "CHOICES"
                  }
               ],

and what we don't yet have is the ability to use the name "selectedOptions" as the primary handle in a match pattern to match the data fragment shown here; and that in turn is because this fragment is not actually an item in the data model. It is an entry in a map.

But the proposed "shallow-copy-all" processing mode for maps and arrays in fact decomposes a map into its entries and applies templates to the individual entries, so what we need, and don't yet have, is a clean way of matching map entries with a known key. The logical syntax for this, given the way lookup expressions work, would be match="?selectedOptions"; and to select the record within the array, we would naturally write match="?selectedOptions?*"

And if we want to match by type, given the proposed syntax in PR #1778, we should write match="?~record(name, value, valuesArray, *); or to qualify it with the context, match="?selectedOptions?~record(name, value, valuesArray, *)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Feature A change that introduces a new feature PR Pending A PR has been raised to resolve this issue XSLT An issue related to XSLT
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants