Google does not correctly merge microdata and json+ld in the same page using same URI id - schema.org

I have a product page with "microdata" and "json+ld" codes. Both of the codes refers to the same #id URI object (http://www.example.org/product#this) so I would expect to "mix/merge" both properties, but instead structured data testing tool shows 2 "individual" products so....
1- Does Google support using two syntax in the same page?
2- Is this well implemented? Can I refer two codes to the same object using itemId for microdata and #id for json+ld?
3- Can this damage my page in terms of structure data indexing?
thanks
You can check it out using this code in test tool:
<div itemscope itemtype="http://schema.org/Product" itemid="http://www.example.org/product#this">
<a itemprop="url" href="http://www.example.org/product">
<div itemprop="name"><strong>Product Name</strong></div></a>
<div itemprop="description">Product Description</div>
<div itemprop="brand" itemscope itemtype="http://schema.org/Organization"><span itemprop="name">Product Brand</span></div>
<div itemprop="offers" itemscope itemtype="http://schema.org/Offer"> <span itemprop="price">100</span><link itemprop="itemCondition" href="http://schema.org/NewCondition" /> New</div>
</div>
<script type="application/ld+json">
{
"#context": "http://schema.org/",
"#id": "http://www.example.org/product#this",
"name": "Product Name",
"#type": "Product",
"image": "http://www.example.com/anvil_executive.jpg",
"mpn": "925872",
"brand": {
"#type": "Thing",
"name": "ACME"
},
"offers": {
"#type": "Offer",
"priceCurrency": "USD",
"price": "119.99",
"itemCondition": "http://schema.org/UsedCondition",
"availability": "http://schema.org/InStock"
}
}
</script>

My guess would be that Google’s Structured Data Testing Tool doesn’t support this for different syntaxes, as it seems to work if using the same syntax. But as they still display the URIs correctly (http://www.example.org/product#this in both cases), you could argue that it’s just the tool’s interface that doesn’t merge them.
However, as far as I know Google does not document to support these subject URIs anyway (but this doesn’t necessarily mean that they don’t support it), so it might not matter for them.
Your example works fine if using http://linter.structured-data.org/: it creates one item with both brands and both offers.

While technically it is feasible to merge data coming from two different syntaxes (read microdata and json-ld) and the Structured Data Linter confirms so, Google does not support it, which means properties won't be merged (and won't satisfy Rich Snippets' requirements).
We have a final confirmation by several actors in the SEO World, including Dan Brickley and Jarno van Driel.
in general you can use both syntaxes side by side, but you won't get
the fine-grained merging of triples by ID that a pure RDF application
might expect (Dan Brickley on Twitter, Jan 14th, 2020, bold mine)
--
I think #danbri already was pretty clear. Highly doubt you'll get a
different answer from other Googlers. (Jarno van Driel on Twitter, Jan 14th, 2020)
The proposed solution so far is to parse the microdata and publish it as JSON-LD.

Related

copyright information for image repositories (schema.org, json-ld)

This is not exactly a technical question, it's about understanding the elements of CreativeWork and ImageObject in schema.org.
When creating structured data for an image, there are some attributes I can use to convey the copyright information, notably:
creator
copyrightHolder
license
This looks quite straightforward for me (even considering the legal differences of "copyright" in the Anglo-American and European worlds).
What I'm looking for is how to include the copyright information from pictures bought on image repositories like iStock. The information provided looks like: istock.com ©acreator ID-000000000.
How is this information meant to be used with schema.org?
As copyrightHolder is meant to be a Person or Organization, using the string 'istock.com ©someone' as the person's or organisation's name doesn't seem to be the right thing to do.
So I came up with this JSON-LD code:
[
{
"#context": "https://schema.org",
"#type": "ImageObject",
"contentUrl": "https://path/to/my/image",
"copyrightHolder": {
"name": "istock.com"
},
"creator": {
"name": "someone"
},
"copyrightNotice": "istock.com ©acreator ID-000000000",
"license": "https://www.istockphoto.com/en/legal/license-agreement"
}
]
I'm still not sure where to put the ID of the image, and also I'm not happy using the id on istock.com as "name" attribute for "creator".
I could also only use the copyrightNotice and not use "creator" and "copyrightHolder" but I'm not sure if I'd meet the legal requirement then.
The schema.org information not really related to any legal requirement issues (It is vocabulary for search engines).
The credit should be visible to the user (With -or- Without schema) if the license requires adding a credit (Who is the copyrightHolder VS creator also not related to schema.org).
More important:
Don't mark up content that is not visible to readers of the page. Google Guidelines
So only add structured data that visible to the users. I guess you don't have in your web design clickable text to istock license (So you don't need to add this).
Even creditText could be enough.
Example (The markup visible to readers):
Basic example - Withtout
<img src="italy-beach.jpg" alt="italy beach."/>
By Jane Doe
copyrights istock.com. Author Leonardo
Basic example - With
<div itemscope itemtype="https://schema.org/ImageObject">
<img src="italy-beach.jpg"
alt="italy beach."
itemprop="contentUrl" />
By <span itemprop="author">Jane Doe</span>
copyrights <span itemscope itemtype="https://schema.org/Organization" itemprop="copyrightHolder"><span itemprop="name">istock.com</span> Author: <span>Leonardo</span>
</div>
image id
You can use https://schema.org/identifier.

JobPosting schema issue: Number is not a known valid target type for the baseSalary property

I'm a little confused about the new JobPosting listing on schema.org, specifically the baseSalary property's expected type.
The docs say that Number is one of the three expected types:
schema JobPosting SS
But when I test the page on Google structured data testing tool I get this warning:
Google warning
stating that 'Number is not a known valid target type for the baseSalary property.'
Nothing weird in the code, just a simple span with the baseSalary itemprop:
<span itemprop="baseSalary">36000</span>
Am I misunderstanding this or missing something?
Cheers
This is not schema.org error. This issue related specifically to google validator & rich snippets recommended properties/guidelines (I agree that an error message does not contribute too much information).
For rich results - Google Required MonetaryAmount as a type for baseSalary (Not number)
"baseSalary": {
"#type": "MonetaryAmount",
"currency": "USD",
"value": {
"#type": "QuantitativeValue",
"value": 40.00,
"unitText": "HOUR"
}
}
Docs & examples:
https://developers.google.com/search/docs/data-types/job-posting
In case someone wants to use HTML elements for the baseSalary instead of ld+json schema:
<span itemprop="baseSalary" itemtype="https://schema.org/MonetaryAmount" itemscope>
<span itemprop="value" itemtype="https://schema.org/QuantitativeValue" itemscope>
<span itemprop="value">30</span>
<span itemprop="unitText">HOUR</span>
</span>
<span itemtype="https://schema.org/salaryCurrency" itemprop="currency">USD</span>
</span>

What is the correct hierarchical schema.org markup for a category page of articles?

I am working on a section of a website that is a combination of 'how-to' articles and 'faq' articles. When excerpted groups of those articles are displayed in a list by category I am not sure what schema to use for the container and the individual articles. Blog and BlogPosting is for blogs and this is not a blog. The articles are not dated or in chronological order. So I am thinking each one is either 'CreativeWork' or 'Article'. But I am not sure what the container's schema should be when they are displayed in excerpted groups or categories.
Edit:
Just to clarify.
Here's a simple version of my markup:
<div itemscope="" itemtype=" ??????? ">
<article itemscope itemtype="http://schema.org/Article"></article>
<article itemscope itemtype="http://schema.org/Article"></article>
<article itemscope itemtype="http://schema.org/Article"></article>
</div>
Firstly don't get too hung up on lists they are not as important [to the machine] as you think.
Try identifying the categories as well as you can. Not having a view into your world, I'll pick a couple of random categories "World War II" & "Europe". Create a page for each (quite possibly these could be your current list pages) and add the Schema.org specific to the category term itself.
{
"#context": "http://schema.org",
"#type": ["Place","DefinedTerm"],
"#id": "http://example.com/concepts/europe",
"name": "Europe",
"sameAs": "http://www.wikidata.org/entity/Q46",
....
{
"#context": "http://schema.org",
"#type":"DefinedTerm",
"#id": "http://example.com/concepts/wwii",
"name": "World War II",
"sameAs": "http://www.wikidata.org/entity/Q362",
....
Then for your articles use the "about" property to reference them to the categories:
{
"#context": "http://schema.org",
"#type":"Article",
"#id": "http://example.com/articles/A123",
"name": "World War II in Europe",
"about": ["http://example.com/concepts/wwii",
"http://example.com/concepts/europe"],
.....
That in theory is all you need to do for the crawler, which should have crawled all your pages, to understand you articles and what they are about.
If you want to be a bit more explicit, on the category pages you could add in the reverse relationships using the subjectOf property:
"subjectOf": ["http://example.com/articles/A123",
"http://example.com/articles/A033"],
Lists of things are of more use to humans, whereas in the machines (eg. The Knowledge Graph) they can work it out from the relationship information you provide.

How should schema.org relational properties be interpreted?

I am currently looking into schema.org to use it with API platform, but there are certain properties that I don't understand.
Let's take https://schema.org/Organization for example:
A Thing (and this case an Organization) has properties, like a name and an address. Now what I don't understand is the property department. However in real life an organization doesn't have just a single department; it has several at least.
Shouldn't that property be oneToMany?
Or do I not understand it and does department link to the parent company, which makes the child Organization (the one with the department property) a department? But if that was to be the case I'd think there would be a Department object instead (extending from the Organization object).
When I define this property in my API Platform's schema.yaml, it expects a single value, just like I would expect from the schema.org's documentation.
Am I missing something? Can someone please explain how I should interpret and use such properties?
Edit: I found out that API Platform expects every property to have a single value, unless specified otherwise. So I have to setup the department property to be oneToMany.
That combined with the great explanation below (the accepted answer) explains it all.
All Schema.org properties can have multiple values. Usually it doesn’t make sense for every property (e.g., birthDate), but it’s possible anyway.
For the department property, the domain (the item which has this property) is the parent organization, and the range (the item which is the value of this property) is the department. In cases like this, where the domain and range expect the same types, you have to interpret the textual definition to make sure for which "direction" the property is intended.
(If, for some reason, you can’t provide multiple values for a property, note that you can use every Schema.org property in the other direction, too, even if no inverse property is defined.)
Examples
An organization (#1) has two departments (#2, #3).
JSON-LD
Using an array ([]):
{
"#context": "http://schema.org/",
"#type": "Organization",
"#id": "#1",
"department": [
{
"#type": "Organization",
"#id": "#2"
},
{
"#type": "Organization",
"#id": "#3"
}
]
}
Microdata
Repeating the property:
<div itemscope itemtype="http://schema.org/Organization" itemid="#1">
<div itemprop="department" itemscope itemtype="http://schema.org/Organization" itemid="#2"></div>
<div itemprop="department" itemscope itemtype="http://schema.org/Organization" itemid="#3"></div>
</div>
RDFa
Repeating the property:
<div typeof="schema:Organization" resource="#1">
<div property="schema:department" typeof="schema:Organization" resource="#2"></div>
<div property="schema:department" typeof="schema:Organization" resource="#3"></div>
</div>

"The attribute publisher.itemtype has an invalid value"

I'm new to code. I'm trying to add Structured Data code for Google reviews on my contact page:
http://www.catnips.co.uk/in-home-mobile-cat-groomer-feline-behaviourist.html
I am using the reviews from my Google Maps client reviews.
Testing it in Google Structured Data Testing Tool, it says
The attribute publisher.itemtype has an invalid value.
I can't work out what I'm doing wrong.
<div itemprop="review" itemscope itemtype="http://schema.org/Review">
<meta itemprop="author" content="Anita Kelsey">
<strong itemprop="itemreviewed">Mobile Cat Grooming</strong> by Jen Crothers<br />
<strong>My Rating:</strong> <span itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating"><img src="http://www.catnips.co.uk/wp-content/uploads/2014/09/5-stars-356x73.png" alt="5 stars" width="356" height="73" class="alignnone size-medium wp-image-4614" /><meta itemprop="ratingValue" content="5" /><meta itemprop="bestRating" content="5" /></span>
</div>
<span itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating">
Anita was absolutely brilliant with my Persian cat Ernie, who was a wriggly customer at times. She skillfully and gently removed the mats on his coat and gave him a very thorough groom. Brilliant, professional and easily a five star service provided from start to finish.
<meta itemprop="ratingValue" content="5" /><meta itemprop="bestRating" content="5" />
The error is not in the code you provided in your question body, but rather in the JSON-LD. In the Structured Data Testing Tool, you can click on an error to be taken to the line in the code that caused the error. This helps you identify what caused the problem.
The error is informing you that the itemtype you provided for the publisher property is invalid. Whilst schema.org does support the type Person for the publisher property of Article, Google does not. Google only supports Organization, not Person, as the type for the publisher property, as mentioned in the Articles Structured Data page on Google Developers.
                          
You can fix error in settings: Yoast SEO > Search Appearance > Knowledge Graph > Choose Company or Person.
Of course you do! You just don't know it yet. ;) Try using this line:
"publisher":{"id":"http://www.catnips.co.uk/#organization"},
"baseSalary": {
"#type": "MonetaryAmount",
"currency": "EUR",
"value": {
"#type": "QuantitativeValue",
"value": 850,
"unitText": "MONTH"
}
}