Creating a villager that will buy zombie pigman swords

Solution 1:

Your villager's ench tag contains id and lvl declared as Integers, while through normal means (enchanting, loot from pigmen) they would instead be Shorts. When matching NBT data, you must match even the datatypes. To declare a Short, you must append the numerical value with an "s".

/summon Villager ~ ~1 ~ {CustomName:"Kunueme",CustomNameVisible:1,Profession:1,Career:0,CareerLevel:18,Offers:{Recipes:[{rewardExp:0b,maxUses:2147483647,uses:0,buy:{id:golden_sword,Count:1,tag:{ench:[{id:21s,lvl:2s}]}},sell:{id:written_book,Count:1,tag:{display:{Name:"A buck"},title:"",author:"The Street",generation:0,pages:["{text:\"\",color:black}"]}}}]}}

Something to keep in mind is that NBT matching for villager trades differs from NBT matching through various commands (such as /scoreboard). For commands, List tag matching (that which encases data in square brackets) is lenient, in that the data you look for is scanned throughout the entire target's list. However, villager trading itself uses strict List detection, in that the list you specify must match exactly as the target item has it specified.

For example, testing for data:["a"] on an entity that contains data:["a","b"] will work fine, since "a" appears somewhere within the target.

If a villager trade looks for ench:[{id:21s,lvl:2s}] on an item that contains ench:[{id:21s,lvl:2s},{id:16s,lvl:1s}], it will not match because the lists are not exactly equal.

Villager trading is the only case as of 1.9 where List matching is strict. All other NBT matching will work fine. For example, if the item you're trading has a string tag that is not specified in the trade, the villager will still accept it and it will not conflict with trading.